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