上手在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…
很清楚的文档