在Java中压缩,在Python-snappy/redis-py集群中解压缩



我正在python中为redis集群编写cron脚本,并使用reds-py集群仅从prod服务器读取数据。一个单独的Java应用程序正在使用快速压缩和Java字符串编解码器utf-8向redis集群进行写入。

我可以读取数据,但不能解码。

from rediscluster import RedisCluster
import snappy

host, port ="127.0.0.1", "30001"
startup_nodes = [{"host": host, "port": port}]
print("Trying connecting to redis cluster host=" + host +  ", port=" + str(port))
rc = RedisCluster(startup_nodes=startup_nodes, max_connections=32, decode_responses=True)
print("Connected",  rc)
print("Reading all keys, value ...nn")
for key in rc.scan_iter("uidx:*"):
value = rc.get(key)
#uncompress = snappy.uncompress(value, decoding="utf-8")
print(key, value)
print('n')
print("Done. exit()")
exit()

decode_responses=False对该评论处理得很好。但是改变CCD_ 2是抛出错误。我的猜测是它无法得到正确的解码器。

Traceback (most recent call last):
File "splooks_cron.py", line 22, in <module>
print(key, rc.get(key))
File "/Library/Python/2.7/site-packages/redis/client.py", line 1207, in get
return self.execute_command('GET', name)
File "/Library/Python/2.7/site-packages/rediscluster/utils.py", line 101, in inner
return func(*args, **kwargs)
File "/Library/Python/2.7/site-packages/rediscluster/client.py", line 410, in execute_command
return self.parse_response(r, command, **kwargs)
File "/Library/Python/2.7/site-packages/redis/client.py", line 768, in parse_response
response = connection.read_response()
File "/Library/Python/2.7/site-packages/redis/connection.py", line 636, in read_response
raise e
: 'utf8' codec can't decode byte 0x82 in position 0: invalid start byte

PS:取消对此行的注释uncompress = snappy.uncompress(value, decoding="utf-8")因错误而中断

Traceback (most recent call last):
File "splooks_cron.py", line 27, in <module>
uncompress = snappy.uncompress(value, decoding="utf-8")
File "/Library/Python/2.7/site-packages/snappy/snappy.py", line 91, in uncompress
return _uncompress(data).decode(decoding)
snappy.UncompressError: Error while decompressing: invalid input 
经过数小时的调试,我终于解决了这个问题。

我在我的java代码中使用xerial/snappy java压缩器,该代码正在写入redis集群。有趣的是,在压缩过程中,xerialSnappyOutputStream在压缩数据的开头添加了一些偏移。在我的情况下,这看起来像这个

"x82SNAPPYx00x00x00x00x01x00x00x00x01x00x00x01xb6x8bx06\******actual data here*****

由于这个原因,解压缩程序无法计算出来。我修改了如下代码,并从值中删除了偏移。它现在运行良好。

for key in rc.scan_iter("uidx:*"):
value = rc.get(key) 
#in my case offset was 20 and utf-8 is default ecoder/decoder for snappy 
# https://github.com/andrix/python-snappy/blob/master/snappy/snappy.py
uncompress_value = snappy.decompress(value[20:])
print(key, uncompress_value)
print('n')

最新更新