从Streambase(Java)发布到Redis的二进制数据读取异常求助
解决Redis中Java序列化数据的Python解析问题
问题出在Java端用StreamBase的ByteOrderedDataOutput序列化tuple存储,而Python端直接用struct.unpack("<s"*len(temp))解析——这种方式完全忽略了Java侧的序列化结构,自然得不到正确结果。
问题根源
ByteOrderedDataOutput是StreamBase的专用序列化工具,它会按照tuple的字段结构(包含字段类型、长度元数据、字节序)来序列化数据,不是简单的原始字节数组堆叠。而你用struct逐个字节解析成字符串,相当于把结构化的二进制数据拆成了无意义的单个字符,必然格式错误。
解决方案
方案1:改用通用序列化格式(推荐)
修改Java端的序列化逻辑,用JSON、Protobuf这类跨语言通用格式存储,Python解析会非常简单。
Java端修改示例(用JSON):
// 引入Jackson库(或其他JSON工具) import com.fasterxml.jackson.databind.ObjectMapper; // 替换原serialize代码块 ObjectMapper mapper = new ObjectMapper(); byte[] valuebuffer = mapper.writeValueAsBytes(tuple);
Python端解析代码:
import redis, json redis_client = redis.StrictRedis(host="abc.com", port=6379, db=0) temp = redis_client.get('samplekey') data = json.loads(temp.decode('utf-8')) print(data)
方案2:还原StreamBase序列化规则解析(如果不能改Java代码)
必须先明确以下信息:
- tuple的字段结构(比如包含哪些字段,每个字段的类型:int、string、float等)
- 序列化时的字节序(通过
tuple.getByteOrder()确定是小端<还是大端>)
然后根据每个字段的类型,用struct逐个解析对应的二进制片段。
示例(假设tuple结构:int(4字节) + 字符串(长度4字节+内容) + float(4字节),小端字节序):
import redis, struct redis_client = redis.StrictRedis(host="abc.com", port=6379, db=0) temp = redis_client.get('samplekey') offset = 0 # 解析int类型字段 id_val = struct.unpack("<i", temp[offset:offset+4])[0] offset += 4 # 解析字符串:先读长度,再读内容 str_len = struct.unpack("<i", temp[offset:offset+4])[0] offset +=4 name = temp[offset:offset+str_len].decode('utf-8') offset += str_len # 解析float类型字段 score = struct.unpack("<f", temp[offset:offset+4])[0] print(id_val, name, score)
注意:ByteOrderedDataOutput的序列化规则是StreamBase内部实现,需要对照官方文档或源码确认每个字段的序列化格式(比如整数是4字节还是8字节,字符串长度用什么类型存储等)。
内容的提问来源于stack exchange,提问作者Krishna Kumar
相关产品推荐
相关产品推荐

