Сжать в Java, распаковать в Python - snappy / redis-py-cluster - PullRequest
0 голосов
/ 17 февраля 2020

Я пишу cron-скрипт на python для redis cluster и использую redis-py-cluster только для чтения данных с сервера prod. Отдельное приложение Java пишет в кластер redis с мгновенным сжатием и java строковым кодом c utf-8 .

Я могу читать данные, но не могу их декодировать.

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 ...\n\n")
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 отлично работает с комментарием. однако изменение decode_responses=True вызывает ошибку. Я думаю, что он не может получить правильный декодер.

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 

1 Ответ

0 голосов
/ 17 февраля 2020

После нескольких часов отладки я наконец смог решить эту проблему.

Я использую xerial / snappy- java компрессор в моем Java коде, который записывает в redis cluster . Интересно, что во время сжатия xerial SnappyOutputStream добавляет некоторое смещение в начале данных сжатия. В моем случае это выглядит примерно так

"\x82SNAPPY\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x01\xb6\x8b\x06\\******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')
...