背景
在项目中,数据经过protobuf序列化后存入Redis集群。这是由c++来做的。
但pb序列化的数据是二进制的,不便于人工查看。
通过RedisDesktopManager查看时,是这样的:
可以使用Python写个脚本反序列化一下,并打印出json格式的字符串,这样调试就方便多了。
Python连接Redis集群
Python连接Redis和连接Redis集群使用的包是不一样的。
默认的redis只能连接Redis单实例,使用redis-py-cluster连接到集群:
pip install redis-py-cluster
代码如下:
#!/usr/bin/env python
# coding: utf-8
from rediscluster import RedisCluster
# 至少需要一个master节点,最好全部输入
startup_nodes = [{"host": "192.168.1.2", "port": 7000},
{"host": "192.168.1.5", "port": 7001},
{"host": "192.168.1.4", "port": 7002}]
# 连接到Redis集群
rc = RedisCluster(startup_nodes=startup_nodes,
# 有密码要加上密码哦
skip_full_coverage_check=True,
decode_responses=False,
password='123456')
rc.set("k", "v")
print(rc.get(""k))
pb_result = rc.hget("key", "field")
print(pb_result)
ok,这样就可以操作Redis了。
注意,连接参数:
- skip_full_coverage_check=True ,这一行一定要写上,不写上可能会报错:
- decode_responses=False,这个其实不用写,默认的就行,但是一定不能是True,因为protobuf编码是二进制的,如果直接解码会报错:
当然,如果你的数据全部都是string形式存储的,设置为True后,可以直接得到str数据,不必再从byte转为str了。
- password:需要密码就写,不需要不写
Json可视化
protobuf支持直接把序列化数据以Json格式展示。
代码如下:
from google.protobuf.json_format import MessageToJson
import demo_pb2 # protoc生成的py文件:protoc sap.proto --python_out=.
# 这是我从Redis中直接复制出来的,注意编码为byte
pb_result = b'\n\x06000001\x12\x0f210415000000001\x1a\x04SZSE \x01(\xecY@\x98\x8b\x02H\xa8\xa7\x02R\x06888888Z\x0810000003b\x06444444j\x0844440930p\xf8\x88\x02'
req = sap_pb2.test() # proto文件中的message,在py中是类
req.ParseFromString(pb_result)
# preserveing_proto_field_name 设置为 True 可以保留 protobuf 的原有字段名,不然会自动转驼峰,如 request_id 会被自动转化为 requestId
print(MessageToJson(req, preserving_proto_field_name=True))
这样就可以输出json格式的结果了。
小结
上述过程的完整代码示例如下:
#!/usr/bin/env python
# coding: utf-8
from rediscluster import RedisCluster
from google.protobuf.json_format import MessageToJson
import demo_pb2 # protoc生成的py文件:protoc sap.proto --python_out=.
# 至少需要一个master节点,最好全部输入
startup_nodes = [{"host": "192.168.1.2", "port": 7000},
{"host": "192.168.1.5", "port": 7001},
{"host": "192.168.1.4", "port": 7002}]
# 连接到Redis集群
rc = RedisCluster(startup_nodes=startup_nodes,
# 有密码要加上密码哦
skip_full_coverage_check=True,
decode_responses=False,
password='123456')
pb_result = rc.hget("key", "field")
print(pb_result)
req = sap_pb2.test() # proto文件中的message,在py中是类
req.ParseFromString(pb_result)
# preserveing_proto_field_name 设置为 True 可以保留 protobuf 的原有字段名,不然会自动转驼峰,如 request_id 会被自动转化为 requestId
print(MessageToJson(req, preserving_proto_field_name=True))
可以看到,使用python来可视化pb还是比较简单的。