MySQL数据导入Redis小记

1 篇文章 0 订阅
1 篇文章 0 订阅

最近在做一些MySQL + Redis结合的工作,其中涉及到了MySQL的数据迁移到Redis的东西,小记一下。

首先,截止2016.11.21,我在Windows环境下都无法用Redis-cli.exe利用pipeline批量插入数据。原因大概是因为字符串等各种格式的问题,同样的命令在Ubuntu的终端下运行良好。Redis版本是Windows开源团队的Redis-x64-3.2.100。地址是MSOpenTech\Redis

Redis 在Windows中的服务端是可以变为Windows服务自启动的,具体命令如下:

redis-server --service-install redis.windows.conf

安装完之后不会自启动,但是可以调用下面命令来进行启动。

redis-server --service-start

导入初期我是直接写了个工具,遍历了MySQL中的所有数据然后插入Redis的,我选择了直接用C#写一个控制台程序,选用的客户端是StackExchange.Redis,然后利用各类的Async进行异步操作(实际上就是使用pipeline),速度还是比较可以的。

后面发布的时候找了一下,Redis本身的客户端可以也利用pipeline来进行批量插入(Mass Insertiong),官方文档(Redis Mass Insertion
h)[http://redis.io/topics/mass-insert],然后结合pipeline,就可以利用脚本将MySQL中的数据转换为Redis-cli可以识别的格式,直接批量插入即可。

在文中,作者给出了示例,用如下的格式进行格式化输入即可:

*<args><cr><lf>
$<len><cr><lf>
<arg0><cr><lf>
<arg1><cr><lf>
...
<argN><cr><lf>

# Where <cr> means "\r" (or ASCII character 13) and <lf> means "\n" (or ASCII character 10).

举个简单的例子,如果要插入一个String类型的key-value值,那么就是

*3\r\n    #表明命令中包含的参数个数
$3\r\n    #表明第一个参数的长度
SET\r\n   #第一个参数,注意各项关键字也都是参数,如这里的SET
$3\r\n    #表明第二个参数的长度
123\r\n   #第二个参数
$4\r\n    #表明第三个参数的长度
4567\r\n  #第三个参数

执行完毕的结果就是插入一个key为123,Value为4567的String类型的Key-Value啦。

而这里涉及到的一个东西就是Redis的Protocol,具体可以查看这里Redis Protocol specification。我也是从这里知道了到底上面那串命令的含义,以及如何处理数据库中空的列的数据。(卖个关子)

我参考了这篇文章
浅谈 Redis 与 MySQL 的耦合性以及利用管道完成 MySQL 到 Redis 的高效迁移 ,里面有讲到如何利用SQL语句将需要的数据格式化成为Redis-cli可以识别的格式,实际上只要两行代码就解决了问题,非常简单。
文章里面展示了这两句核心代码:

# 这是SQL语句,格式化数据用
cat mysql_to_redis.sql 
SELECT CONCAT(
  "*4\r\n",
  \'$\', LENGTH(redis_cmd), \'\r\n\',
  redis_cmd, \'\r\n\',
  \'$\', LENGTH(redis_key), \'\r\n\',
  redis_key, \'\r\n\',
  \'$\', LENGTH(hkey), \'\r\n\',
  hkey, \'\r\n\',
  \'$\', LENGTH(hval), \'\r\n\',
  hval, \'\r\'
)
FROM (
  SELECT
  \'HSET\' AS redis_cmd,
  \'david\' AS redis_key,
  myname AS hkey,
  mymoney AS hval
  FROM david_lin
) AS t;
#这是命令行/终端语句, 直接执行就可以导入啦
mysql -uroot -poracle test --skip-column-names --raw < mysql_to_redis.sql | redis-cli --pipe

只要简单执行上述的两行代码,就可以直接迁移。
然而在我的使用过程中发现了一个问题,由于业务关系,我的基础业务数据库中会存在空列,而这个又是关键数据,需要迁移到Redis中的。单纯利用上述的SQL语句,进行操作的时候,Redis-cli会抛出“Unknown Command NULL on Redis.”
我们知道,Redis是可以存储二进制数据的(而实际上Redis存储的Value都是二进制格式存储的),所以空数据理论上是可以存入的。然而根据观察,Redis的空数据,表现为空字符串形式,即。所以,我们需要将我们数据库中为NULL的数据,转换成为”进行输出。
而Redis-cli接受空字符串的时候,是可以根据参数长度进行判断的。具体表现为“$0\r\n\r\n”,正好一致。

所以上述的命令应该修改为如下:

cat mysql_to_redis.sql 
SELECT CONCAT(
  "*4\r\n",
  \'$\', LENGTH(redis_cmd), \'\r\n\',
  redis_cmd, \'\r\n\',
  \'$\', LENGTH(redis_key), \'\r\n\',
  redis_key, \'\r\n\',
  \'$\', LENGTH(hkey), \'\r\n\',
  hkey, \'\r\n\',
  \'$\', LENGTH(hval), \'\r\n\',
  hval, \'\r\'
)
FROM (
  SELECT
  \'HSET\' AS redis_cmd,
  \'david\' AS redis_key,
  myname AS hkey,
  if(mymoney is not null, mymoney, '') AS hval
  FROM david_lin
) AS t;

看出来区别了吗~ 因为NULL数据长度肯定为0,所以上面一部分不需要修改,只需要修改下面的SELECT语句即可。

这样就可以将带有空行的数据也一次导入啦~!

另外需要注意的是,上述终端命令需要根据自己的实际情况,将数据库所在的ip和端口等都填上哦。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值