0%

This article will first talk about a wrong use case with etcd lease, and then based on that case, I will dig into the design principle of etcd lease and some use scenario with etcd lease.

A wrong use case with etcd lease

There exist two roles in the following scenario, one is client and the other one is coordinator. More than one clients could exist at the same time. Each of them has an unique ID, and when a new client starts it applies a new lease from etcd and puts a key corresponding to the client ID with lease as option. The client must call KeepAlive of its lease periodically to keep lease not timeout. Once the lease is timeout and deleted by etcd server, the client becomes illegal and should not access the etcd resource anymore. The coordinator monits the client ID key, when a new client registers, it allocates new resource/task to this client, which can be represented by a client ID relevant key value. And when it detects client ID key deleted (which means the client lease timeout), it will recycle the allocated resource of this client.

Here we use a etcd session to maintain client lease and lease keepalive, a simple work model of client is as follows

Read more »

Etcd is a distributed reliable key-value store written by golang and native golang client binding is provided in its official repository, which makes it very convenient as well as robust to write golang code to communicate with etcd server. Here robust means the etcd client should guarantee correctness and high availability under faulty conditions, more details can be found in etcd official client design document. This article summarizes some best practises with etcd client library from the lessons I learned from the production environment. To explain some implementation mechanisms I will also link to etcd source code (mainly based on branch release-3.4).

Consume data from the watch response channel ASAP

Watch works with a bi-directional gRPC stream between watch client and etcd server, the most common way to use watch is as follows, receive keyspace changed result from the watch channel and consume these KV events one by one.

Read more »

本文会介绍如何使用 go 编写 redis loadable modules,并分析编写模块和使用cgo可能遇到的坑。

什么是redis loadable modules

可加载模块是redis最新加入的功能,目前需要在unstable分支才可以使用。简单说模块系统是redis的C代码暴露出一些API,定义在头文件redismodule.h中,外部模块引用该头文件即可访问所有的API函数,这些API提供了包括访问redis的字典空间、调用redis命令、向客户端返回数据等诸多功能。外部模块是以动态库的形式被redis server加载并使用,可以在redis server启动时加载,也可以在启动后动态加载。更多的细节可以参考文档redis module INTRO

在此之前想对redis扩展有两种方案:一是利用lua脚本;另一种则需要修改redis源码,类似于Kit of Redis Module Tools提供的方案。lua脚本的扩展性有限,并且lua是通过redis的上层API来调用redis命令的,无法直接访问底层的存储数据,调用redis更底层的API;修改源码的方案就更加hack,是没有办法不断与上游分支合并的。

Read more »

最近使用了 rq 这个简单的队列处理库,其中有一些任务需要使用MySQL的连接或者redis的连接,对此有一些思考。

MySQL/redis的连接复用

rq 提供了两种 worker 模型:基于 fork 的 worker 模型和直接在主线程执行任务的 worker 模型。基于 fork 的 worker 在执行任务之前先 fork 一个子进程,在子进程中执行具体的任务,父进程等待子进程执行返回。在基于 fork 的 worker 模型下,如果在父进程有一个 MySQL/redis 连接,由于子进程会继承父进程的地址空间,具有相同的打开文件、socket、管道等,所以子进程中也有同样的 MySQL/redis 连接,那么在这种情况下这个连接可以直接使用么?通过以下代码简单测试一下,连接 MySQL 使用 torndb ,连接 redis 使用 redis-py

Read more »

有时候因为网络、安全等原因,我们不能通过 ssh 直接连接到目标主机,而是需要通过代理服务器或跳板机实现连接。本文总结通过代理或跳板机使用 ssh 的各种方法,并且分析这些方法的基本原理。

我们设定本地主机的地址为 homepc,绑定有公网 ip;运行有各类代理的代理服务器或跳板机地址为 proxy-server,proxy-server 上绑定一个公网 ip,同时绑定一个内网 ip(假定为10.0.10.252);需要连接的目标主机 target-server,绑定内网 ip(假定为 10.0.10.25)。所有的用户名、登录用户名使用 apple。

Read more »

本文是上一篇文章 python 拾遗 的延续,继续整理 python 的一些使用技巧,以及一些可能被忽略的细节

注意: 以下讨论主要为 Python2.7 版本, Python 3 的内容有待跟进

Read more »

整理 python 使用的一些技巧,以及一些可能被忽略的细节,很多在文档可以查找到的内容将不会过多的描述,更多以外链的形式存在。

注意: 以下讨论主要为 Python2.7 版本, Python 3 的内容有待跟进

Read more »

Pro Git 是一本用来学习 git 使用很不错的书,从 progit 这个开源项目可以获得这本书的全部内容,下边介绍在 Ubuntu Server 12.04 环境下制作电子书的过程。

安装依赖

1. ruby, rubygems

参考 Ruby-China 的 wiki

2. rdiscount

markdown 使用的模板,通过 rubygems 安装

1
2
3

$ gem install rdiscount

3. calibre

calibre 是一款开源的电子书管理软件,生成 epub 或 mobi 格式需要安装。

1
2
3

$ sudo apt-get install calibre

Read more »

概述

APScheduler 是由 python 实现的一个轻量级任务调度器,它可以按照一定间隔(IntervalTrigger)、指定时间(2.1中的SimpleTrigger/3.0中的DateTrigger)或者以类似 cron(CronTrigger) 的形式触发待执行任务(即调用函数或者调用 python 的 callable 对象)。现在 pypi 上的稳定版是 APScheduler 2.1.1,3.0 版本在 class Scheduler 中移除了针对不同 trigger 的 add_trigger_job() 接口,统一为 add_job(),但是底层实现变化不大。我主要看了 2.1.1 的代码。代码很简洁,加起来一共2049行。

模块组织

  • Scheduler 调度器的核心部分,负责对 job 的管理和调度,用户使用添加/移除任务,启动调度器都通过 Scheduler 提供的接口完成。

  • Job 封装了需要调度的任务,每一个 Job 实例是在 Scheduler 添加 job 时被初始化,具体的初始化参数决定了调度被触发的形式(3类不同的trigger)。

  • Trigger 包含 SimpleTrigger,IntervalTrigger和 CronTrigger 三个类。Trigger 的作用就是计算下一次触发任务的时间。

  • JobStore 抽象基类,针对任务存储的介质有多个实现,包括基于内存(RAMJobStore)、使用shelve的简单持久化存储(ShelveJobStore)、使用数据库存储(RedisJobStore,MongoDBJobStore)等。如果不指定参数默认使用 RAMJobStore,使用持久化的 JobStore 的目的是在 Scheduler 重启之后能够恢复原有的任务调度。

底层实现

从分析 Scheduler 类入手,首先看项目中自带的example:

Read more »

手头四台服务器,准备搭建一个小的云平台,了解了几种不同的方案,包括Vmware Esxi,Xen,OpenStack 等。先把各种方法都试一试,然后确定一个具体实施。之前有使用过 Vmware ESXi,虽说 ESXi 可以免费使用,但是 Vmware 浓厚的商业气息让我有种道不同不相为谋的感觉。XenServer 最近有开源,于是昨天花了一个下午尝试了一下。

安装 XenServer 和 XenCenter

首先去官网下载 XenServer 的镜像文件,我下载了 6.2.0 版本。XenServer 本身其实就是一个 Linux 操作系统,于是服务器直接通过启动 bios 引导安装 XenServer,安装过程中配置好 root 的密码以及网络信息,这样就可以通过管理工具管理 XenServer 了。

使用的管理工具是 Windows 版的,貌似有 Linux 版本的OpenXenCenter,我没有试验。进入 XenCenter,服务器是四网卡,现在接了0,2号网卡。2号网卡连接外网,配有有一个 166.111.xx.yy的 ip。0号网卡接内部网络,ip 设为 192.168.10.254。配置如下图:

Read more »