上手在github提交了python gevent etcd的非阻塞模块。 正好这两天寂寞的很,打算再重写下etcd 输入更改数据这块的逻辑。 搜相关文档的时候,发现很多资料对于etcd http api写入数据描述,很是模糊片面,愣是没找到像样点的代码样式。正好趁着有时间,就把这方面的资料给补全下。或许对大家有些用处。
关于数据写入etcd http api的文档地址:
下面是写入修改的etcd api接口样式:
/v2/keys/{ path }[prevValue=string||prevIndex=int][prevExist=boolean]
Method : PUT
我们会注意到etcd写入数据时,会有三个参数 prevValue、prevIndex、prevExist 。
prevExist
判断是否存在
prevExist = True ,不管有没有这个key,都会写入value ,可以理解为强制写入
client.write(‘/a/k3′,’xiaorui.cc’,prevExist=True)
如果 prevExist = False的话 ,就会异常报错 ,etcd的默认参数就是 False
client.write(‘/a/k3′,’xiaorui.cc’,prevExist=False)
----> 1 client.write('/a/k3','testa',prevExist=False)
/usr/local/python2.7/lib/python2.7/site-packages/etcd/client.pyc in write(self, key, value, ttl, dir, append, **kwdargs)
404 path = self.key_endpoint + key
405
--> 406 response = self.api_execute(path, method, params=params)
407 return self._result_from_response(response)
408
/usr/local/python2.7/lib/python2.7/site-packages/etcd/client.pyc in api_execute(self, path, method, params, timeout)
800 self._machines_cache = self.machines
801 self._machines_cache.remove(self._base_uri)
--> 802 return self._handle_server_response(response)
803
804 def _handle_server_response(self, response):
/usr/local/python2.7/lib/python2.7/site-packages/etcd/client.pyc in _handle_server_response(self, response)
817 r = {"message": "Bad response",
818 "cause": str(resp)}
--> 819 etcd.EtcdError.handle(r)
/usr/local/python2.7/lib/python2.7/site-packages/etcd/__init__.pyc in handle(cls, payload)
276 exc = cls.error_exceptions.get(error_code, EtcdException)
277 if issubclass(exc, EtcdException):
--> 278 raise exc(msg, payload)
279 else:
280 raise exc(msg)
EtcdAlreadyExist: Key already exists : /a/k3
prevValue
当匹配prevValue 值时,才进行写入数据,也就是说,如果/a/xiaorui值不为mm,那么就报错。
client.write(‘/a/xiaorui’,’nima’,prevValue=’mm’)
prevIndex
这个的用法同prevValue ,我这里就不再废话了。 prevIndex对于我来说,很少会用的。
python的代码样式:
from urllib2 import Request, urlopen
from urllib import urlencode
values = urlencode([value=string][&ttl=int])
headers = {"Content-Type": "application/x-www-form-urlencoded"}
request = Request("http://xiaorui.cc/v2/keys/{ path }[prevValue=string||prevIndex=int][prevExist=boolean]", data=values, headers=headers)
request.get_method = lambda: 'PUT'
response_body = urlopen(request).read()
print response_body
—result:
Response
200 (OK)
curl的命令样式:
curl --include \
--request PUT \
--header "Content-Type: application/x-www-form-urlencoded" \
--data-binary '[value=string][&ttl=int]' \
'http://xiaorui.cc/v2/keys/{ path }[prevValue=string||prevIndex=int][prevExist=boolean]'
上面的方法有些麻烦,接口的样式让人有些发愣,其实etcd提供了让人看起来更加舒服的接口。
重新开始测试下,首先我们put记录,因为是第一次对这个key进行操作,所以成功。
curl -L http://xiaorui.cc:4001/v2/keys/a/k2 -XPUT -d value=one
{
"action": "set",
"node": {
"createdIndex": 2,
"key": "/a/k2",
"modifiedIndex": 2,
"value": "one"
}
}
当我们再次put的时候,会提示key已经存在。 怎么破? 加入prevExist=true就可以了。 前面怎么有说过,prevExist的强制写入。
curl -L http://xiaorui.cc:4001/v2/keys/a/k2 -XPUT -d value=one
{
"cause": "/a/k2",
"errorCode": 105,
"index": 39776,
"message": "Key already exists"
}
如果key不等于prevValue值的话,那么就会提示失败 !
curl -L http://xiaorui.cc:4001/v2/keys/a/k2?prevValue=two -XPUT -d value=three
{
"cause": "[two != one]",
"errorCode": 101,
"index": 8,
"message": "Compare failed"
}
如果prevValue跟之前的value想匹配的话,就会执行成功。
curl -L http://xiaorui.cc:4001/v2/keys/a/k2?prevValue=one -XPUT -d value=two
{
"action": "compareAndSwap",
"node": {
"createdIndex": 8,
"key": "/a/k2",
"modifiedIndex": 9,
"value": "two"
},
"prevNode": {
"createdIndex": 8,
"key": "/a/k2",
"modifiedIndex": 8,
"value": "one"
}
}
删除key的样例
curl -L http://xiaorui.cc:4001/v2/keys/a/k2?prevValue=one -XDELETE
{
"action": "compareAndDelete",
"node": {
"key": "/a/k2",
"modifiedIndex": 9,
"createdIndex": 8
},
"prevNode": {
"key": "/a/k2",
"value": "one",
"modifiedIndex": 8,
"createdIndex": 8
}
}
END…

很清楚的文档