如何将约100万个JSON文件批量加载到Redis并存储为JSON类型?
Redis批量加载JSON文件:String vs JSON类型问题
问题背景
我基于Redis官方批量加载文档写了一段Bash代码,能正常运行,但Redis Insights显示存储的值是string类型而非JSON类型。所有待存储的文件本身都是JSON文件,我想搞清楚两个问题:
- 是否不用修改?string类型是否足够,会不会限制后续的查询能力?
- 如果必须改成JSON类型,怎么调整代码才能保证批量加载的性能,同时让Redis识别这些值为有效JSON?
附上我的原代码:
head=$(redis-cli -h $redis_server get .git-head) if [[ ! $head ]]; then redis-cli -h $redis_server flushdb for fileOrFolder in $(ls -1); do time { find $fileOrFolder -type f | LC_ALL=C xargs -n1 bash -c 'echo -e *3\\r\\n\$3\\r\\nSET\\r\\n\$${#0}\\r\\n$0\\r\\n\$$(stat -c%s $0)\\r && cat $0 && echo -e \\r' | redis-cli -h $redis_server --pipe } done redis-cli -h $redis_server set .git-head $(git rev-parse HEAD) fi
String类型是否够用?
完全够用,不会限制查询能力。只要你的值本身是合法的JSON字符串,Redis的所有JSON操作命令(比如JSON.GET、JSON.PATH、JSON.SET修改节点等)都能直接对这些string类型的值生效。Redis不会因为值存在string键里就拒绝解析它的JSON结构,只是Redis Insights会把它标记为string类型而已。
如果你的业务需求只是读取完整JSON内容或者基于JSON结构做查询、修改,用string类型存储反而更高效——省去了JSON类型存储的额外校验和转换开销,批量加载的性能也更好。
改成JSON类型并保持性能的方法
如果一定要让Redis把值识别为JSON类型(比如在Redis Insights里显示为JSON格式,或者想强制校验值的JSON合法性),只需要把原代码里的SET命令换成JSON.SET,同时调整RESP协议的格式即可,不会影响批量加载的性能。
修改后的核心代码片段如下:
find $fileOrFolder -type f | LC_ALL=C xargs -n1 bash -c ' content=$(cat "$0") key_len=${#0} content_len=${#content} # 构造RESP格式的JSON.SET命令:JSON.SET <键名> . <JSON内容> echo -e "*4\r\n\$7\r\nJSON.SET\r\n\$$key_len\r\n$0\r\n\$1\r\n.\r\n\$$content_len\r\n$content\r\n" ' | redis-cli -h $redis_server --pipe
关键改动点:
- 命令替换:把
SET换成JSON.SET,命令格式变为JSON.SET <键名> . <JSON内容>(.表示JSON的根路径) - RESP数组长度调整:原来的
*3(SET命令有3个参数)改成*4(JSON.SET有4个参数) - 命令名长度修改:
SET是3个字符,对应\$3;JSON.SET是7个字符,对应\$7 - 新增根路径参数:添加
.作为JSON路径参数,长度为\$1
这样修改后,Redis会将值存储为JSON类型,同时依然使用--pipe进行批量加载,性能和原方案几乎一致——因为都是基于RESP管道批量发送命令,只是命令类型和参数结构略有调整。
内容的提问来源于stack exchange,提问作者mark
相关产品推荐
相关产品推荐

