Redis数据迁移过程,使用jedis客户端,需要注意区分string和byte命令转换字符编码不一致的问题,使用不当会导致丢数据

news/2024/10/29 16:19:39/

1.了解String与byte之间存在的字符编码映射规则(java为例)

string与byte来回转换,需要指定一样字符编码规则

详细原因请参考:关于Java中bytes到String的转换-阿里云开发者社区 

简单来说

(1)string和byte转换之间需要指定字符编码参数Charset.defaultCharset(),默认不指定的情况下,使用的是utf-8编码,所以一般情况下相互转换使用的都是同一种编码utf-8,byte和string之间的来回转换不会出现错误。如以下代码示例:

public static void main(String[] args) {byte[] original2 = new byte[] {(byte) 0xef, (byte) 0x8f, (byte) 0xff};byte[] transformed2 =new String(original2, Charset.defaultCharset()).getBytes(Charset.defaultCharset());System.out.println(Arrays.toString(original2));System.out.println(Arrays.toString(transformed2));System.out.println(Arrays.equals(original2, transformed2));}

(2)指定的字符编码不一致,导致string和byte转换出现错误的场景

  • 转换过程,指定的字符编码不一致

    string转byte时,指定了使用GBK字符编码,byte转回string字符时,使用了默认的utf-8。

  • 跨机器的代码转换

    在A机器上,string转byte时,使用的默认字符编码与系统一致是GBK字符编码。

    把byte数据发送给B机器处理,byte转string时,使用的默认字符编码与系统一致是utf-8字符编码

参考utf-8编码规范

https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf 

2.redis的使用场景

数据处理经过

现在有个命令需要处理:set a b

处理过程是,通过jedis客户端发送string或者byte数据到redis,redis底层只存byte格式的数据。

具体流程

(1)使用jedis存string ==》默认使用utf-8转byte存储 ==》默认读取使用utf-8解码读取

(2)使用jedis存string ==》指定字符编码,把string转byte存储 ==》指定字符编码,从byte转string后读取数据

(3)使用任意字符编码把string转byte后,使用jedis存byte ==》与编码无关直接存储 ==》与编码无关直接读取

jedis指定编码规则的源码位置:redis.clients.jedis.Client#set(java.lang.String, java.lang.String)

public void set(String key, String value) {this.set(SafeEncoder.encode(key), SafeEncoder.encode(value));}看看encode的方法,默认指定了UTF-8public static byte[] encode(String str) {try {if (str == null) {throw new JedisDataException("value sent to redis cannot be null");} else {return str.getBytes("UTF-8");}} catch (UnsupportedEncodingException var2) {throw new JedisException(var2);}}

字符编码丢失的问题

参考上面的具体流程可知,底层redis的存储不考虑字符编码,只存最终的byte格式数据。

使用jedis客户端的过程,可以指定string转换byte时使用的字符编码,比如utf-8、gbk等等,但是使用的什么字符编码,这个不会随着数据本身存储到redis底层。可以理解在这个过程中,使用的字符编码规则是什么丢失了。

总结:只从底层的数据byte本身,无法知道用户使用的什么字符编码把string转换成byte,然后存进来的。所以在对redis底层的数据,做数据迁移的过程中,最好不要存在改动原始byte数据的动作。比如你如果使用了new string(byte)数据,那就默认使用了utf-8的编码对它进行了转换,可能导致数据转换错误。


http://www.ppmy.cn/news/42141.html

相关文章

Cont. DB Project ----- MySQL Python Project

Function achieve (Cont.) Item Search 添加一个新函数search_item,用于实现商品搜索的功能。参数:keyword (为了模糊查询) # search items by keywords def search_item(keyword):cursor, db connect_database()sql f"SE…

《花雕学AI》06:抢先体验ChatGPT的九个国内镜像站之试用与综合评测

最近ChatGPT持续大火,大家们是不是在网上看到各种和ChatGPT有趣聊天的截图,奈何自己实力不够,被网络拒之门外,只能眼馋别人的东西。看别人在体验,看别人玩,肯定不如自己玩一把舒服的啊。 上一期&#xff0…

FIFO的工作原理及其设计

1.简介 FIFO( First Input First Output)简单说就是指先进先出。FIFO存储器是一个先入先出的双口缓冲器,即第一个进入其内的数据第一个被移出,其中一个口是存储器的输入口,另一个口是存储器的输出口。 对于单片FIFO来说,主要有两种…

JDBC03-批处理、连接池、DBUtils、事物、DAO通用方法

1. 封装 JDBCUtils 【关闭、得到连接】 1.1 说明 1.2 代码实现 工具类 JDBCUtils package com.hspedu.jdbc.utils;import java.io.FileInputStream; import java.io.IOException; import java.sql.*; import java.util.Properties; /** * 这是一个工具类,完成 my…

重装系统下载网址

[置顶]无论会不会安装系统,都一定会需要,觉得内容不错欢迎一键三连哦 稳定 | 方便 | 好用 1、MSDN 用过最简单好用,下载不限速,支持迅雷、IDM多种下载方式 https://www.xitongku.com 2、Windows系统下载仓储站 为小白重装系统提供…

yum源配置

一、互联网yum源(centos7为例): cd /etc/yum.repos.d/ && rm -f *.repo;wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo…

docker常用步骤

1、进入一个已经在运行的容器 $ sudo docker ps $ sudo docker exec -it 775c7c9ee1e1 /bin/bash 2、启停容器 假如容器名称是nginx 停止容器nginx docker stop nginx 启动容器nginx docker start nginx 3、复制内容到容器中 docker cp /Downloads/xxx.zip 1faca6a70742:/opt…

(六)【软件设计师】计算机系统—原码反码补码移码

文章目录一、数据表示二、原码三、反码四、补码五、移码六、范围七、总结一、数据表示 各种数值在计算机中表示的形式称为机器数,其特点是采用二进制计数制,数的符号用0和1表示,小数点则隐含,表示不占位置。机器数对应的实际数值称…