Mysql如何高效的迁移到Redis

 

 

1.需求
前端任务需要将几百万数据某几个关键字段组合成字符串从mysql导入redis 列表中,发现网上大都数linux 以及 redis为key-value形式的hash值,而我需要的是字符串列表,找不少资料始终找不到,无奈只能自己研究了 ..希望能给到大家启发。

 

2.下载redis 并启动
这个无需多言简单介绍下 

首先去 :https://github.com/MSOpenTech/redis/releases 下载  Redis-x64-3.2.100(其他版本亦可)

然后启动 也可以解压之后打到服务里面启动 

  1.打到服务里面默认端口为6379

     redis-server --service-install redis.windows.conf --service-name RdisDb--port 6380

  2.或者cmd进入目录直接启动

     启动命令:redis-server.exe redis.windows.conf

 

3.将mysql 数据导入redis中

参考资料:http://blog.itpub.net/26515977/viewspace-1208145/

首先我的数据库格式是这样的

redis 要求的格式是这样的


*<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).

举个例子


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

我现在需要的存入数据库的是这种格式

1.将下面sql保存为sql脚本,存入redis 目录中


SELECT CONCAT(  
  "*3\n",  
  '$', LENGTH(redis_cmd), '\n',  
  redis_cmd, '\n',  
    '$', LENGTH(redis_key), '\n',  
  redis_key, '\n',  
  
  '$', LENGTH(CONCAT("http://baike.baidu.com/item/",hval,"/",hkey)), '\n',CONCAT("http://baike.baidu.com/item/",hval,"/",hkey)  
  
)  
FROM (  
  SELECT 
  'LPUSH' as redis_cmd,  
  'ErrorUrl-data' AS redis_key,  
  newLemmaId AS hkey,  
  item AS hval  
  FROM add_doc_copy1
) AS t

上面执行出来就是这个样子 就代表成功

2.cmd进入目录执行写入命令

 

    如果  redis中设置了密码 用下面

   mysql -h 127.0.0.1 -uroot -p123456 baike_update --default-character-set=utf8 --skip-column-names --raw < mysql-to-redis.sql | redis-cli.exe -h 127.0.0.1 -p 6381 -a root --pipe

 

  如果没有密码

mysql -h 127.0.0.1 -uroot -p123456 baike_update --default-character-set=utf8 --skip-column-names --raw < mysql-to-redis.sql | redis-cli.exe --pipe

 

解释:mysql -h 127.0.0.1 -uroot -p123456 (数据库登陆)          baike_update(数据库名)    --default-character-set=utf8 (数据库有特殊符号等最好加上这句,也可以去掉 )  --skip-column-names --raw < mysql-to-redis.sql | redis-cli.exe -h 127.0.0.1 -p 6381 -a root --pipe (redi执行命令)

 

 

3.如果需要存入key-value形式的可以使用下面sql
 

SELECT CONCAT(  
  "*4\n",  
  '$', LENGTH(redis_cmd), '\n',  
  redis_cmd, '\n',  
    '$', LENGTH(redis_key), '\n',  
  redis_key, '\n',  
  '$', LENGTH(hkey), '\n',  
  hkey, '\n', 
  '$', LENGTH(CONCAT("http://baike.baidu.com/item/",hval,"/",hkey)), '\n',CONCAT("http://baike.baidu.com/item/",hval,"/",hkey)  
  
)  
FROM (  
  SELECT 
  'HSET' as redis_cmd,  
  'ErrorUrl-data' AS redis_key,  
  newLemmaId AS hkey,  
  item AS hval  
  FROM baike_update.add_doc  
) AS t

 

############################################################################################

首先造数据

由于环境限制,所以这里没有用真实数据来实现导入,那么我们就先使用一个存储过程来造一百万条数据把。使用存储过程如下:

DELIMITER $$
USE `cb_mon`$$


DROP PROCEDURE
IF EXISTS `test_insert` $$CREATE DEFINER = `root`@`%` PROCEDURE `test_insert` ()
BEGIN
	DECLARE
		i INT DEFAULT 1;
WHILE i <= 1000000 DO
	INSERT INTO t_book (id, number, NAME, descrition)
VALUES
	(
		i,
		CONCAT("00000", i),
		CONCAT('book', i),
		CONCAT('book_description', i)
	);
SET i = i + 1;
END
WHILE;
COMMIT;
END$$



DELIMITER ;

 

CALL test_insert();

 

linux下版本

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,
			id AS redis_key,
			NAME AS hkey,
			descrition AS hval
		FROM
			cb_mon.t_book
	) AS t
LIMIT 1000000

win下版本

SELECT
	CONCAT(
		"*4\n",
		"$",
		LENGTH(redis_cmd),
		"\n",
		redis_cmd,
		"\n",
		"$",
		LENGTH(redis_key),
		"\n",
		redis_key,
		"\n",
		"$",
		LENGTH(hkey),
		"\n",
		hkey,
		"\n",
		"$",
		LENGTH(hval),
		"\n",
		hval
	)
FROM
	(
		SELECT
			"HSET" AS redis_cmd,
			id AS redis_key,
			NAME AS hkey,
			descrition AS hval
		FROM
			cb_mon.t_book
	) AS t
LIMIT 1000000

 

并将内容保存至redis.sql 文件中。

 

脚本执行如下:

#!/bin/bashstarttime=`date +'%Y-%m-%d %H:%M:%S'`docker exec -i 899fe01d4dbc mysql --default-character-set=utf8   --skip-column-names --raw < ./redis.sql| docker exec -i 4c90ef506acd redis-cli --pipeendtime=`date +'%Y-%m-%d %H:%M:%S'`start_seconds=$(date --date="$starttime" +%s);end_seconds=$(date --date="$endtime" +%s);echo "脚本执行耗时: "$((end_seconds-start_seconds))"s"

手动执行(本地需要安装mysql和redis)

mysql -uroot -Dcb_mon --default-character-set=utf8 --skip-column-names --raw < test.sql | redis-cli -h 192.168.0.105 -p 6379  --pipe


总结

  1. redis单线程执行命令,避免了线程切换所消耗的时间,但是在超大数据量级下,其发送、响应接收的时延不可忽视。
  2. 网络nc命令的应用场景,及在数据导入时存在的缺点。
  3. redis RESP协议的理解和应用。
  4. 百万量级Mysql数据的Redis快速导入案例。

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值