一:编写sql脚本 sql.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;
*4\r\n #表明命令中包含的参数个数
$4\r\n #表明第一个参数的长度
HSET\r\n #第一个参数,注意各项关键字也都是参数,如这里的HSET
$4\r\n #表明第二个参数的长度
david\r\n #第二个参数
$4\r\n #表明第三个参数的长度
liu1\r\n #第三个参数
$4\r\n #表明第四个参数的长度
1000\r\n #第四个参数
mysql CONCAT函数用于将多个字符串连接起来,形成一个单一的字符串,各字符串之间会以空格分割。
拼接起来后的数据结构是:
4\r\n $4\r\n HSET\r\n $4\r\n david\r\n $4\r\n liu1\r\n $4\r\n 1000\r\n
… …
类似以上数据,多行。jedis各方法底层实现操作redis,也是都是组合成这种数据格式,通过socket连接发往redis服务器。
二:使用指令进行导入
mysql -uroot -ppassword -h 127.0.0.1 database
–default-character-set=uft8 --skip-column-names --raw < ~/sql.sql | /usr/local/bin/redis-cli -h 127.0.0.1 -p 6379 -a 12345678 --pipe
mysql -h 主机地址 -u 用户名 -p密码 [dbname]
这里的-p和密码是一起的不能分开写,如果确定使用某个数据库,可在其后加上数据库名。
让 MySQL 不输出列名 可以用 -N 或者 --skip-column-names 参数(skip–跳过)。
-r, --raw //写列的值而不转义转换。通常结合–batch选项使用。
redis-cli -h 地址 -p 端口 -a 密码
redis命令从执行到结果返回,有一定的时延,即便采用多个redis客户单并发插入,也很难提高吞吐量,因为,只有非阻塞I/O只能针对有限个连接操作。
那么如何高效的插入呢?
官方在2.6版本推出了一个新的功能-pipe mode,即将支持Redis协议的文本文件直接通过pipe导入到服务端。
pipe的实现原理:
它会尽可能快的将数据发送到Redis服务端,并尽可能快的读取并解析数据文件中的内容,一旦数据文件中的内容读取完了,它会发送一个带有20个字节的字符串的echo命令,Redis服务端即根据此命令来确认数据已插入完毕。
另外:
Redis中的空数据是以字符串空串的形式存储的,而MySQL中则为NULL,所以在导入到Redis的时候出错了。
解决方法:可以将数据库中为NULL的数据转换成空串,再导入到Redis中。eg:if(cloumn is not null, cloumn, ‘’) AS cloumn1
导入后,再记得看看数据在redis的存储方式,根据这个存储方式,可以进行快速的频繁的读取。。。。