使用python同步mysql到redis?由于数据较多,一条一条读出来写到redis太慢,有没有可以批量操作的。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用python同步mysql到redis?由于数据较多,一条一条读出来写到redis太慢,有没有可以批量操作的。相关的知识,希望对你有一定的参考价值。
redis只有一台服务器,mysql存在多个不同的主机上,数据库库名和表名表结构都是一样的,怎么才能批量同步到redis,有没有库可以用?
MYSQL快速同步数据到Redis举例场景:存储游戏玩家的任务数据,游戏服务器启动时将mysql中玩家的数据同步到redis中。
从MySQL中将数据导入到Redis的Hash结构中。当然,最直接的做法就是遍历MySQL数据,一条一条写入到Redis中。这样没什么错,但是速度会非常慢。如果能够想法使得MySQL的查询输出数据直接能够与Redis命令行的输入数据协议相吻合,可以节省很多消耗和缩短时间。
Mysql数据库名称为:GAME_DB, 表结构举例:
CREATE TABLE TABLE_MISSION (
playerId int(11) unsigned NOT NULL,
missionList varchar(255) NOT NULL,
PRIMARY KEY (playerId)
);
Redis中的数据结构使用哈希表:
键KEY为mission, 哈希域为mysql中对应的playerId, 哈希值为mysql中对应的missionList。 数据如下:
[root@iZ23zcsdouzZ ~]# redis-cli
127.0.0.1:6379> hget missions 36598
"\"10001\":\"status\":1,\"progress\":0,\"10002\":\"status\":1,\"progress\":0,\"10003\":\"status\":1,\"progress\":0,\"10004\":\"status\":1,\"progress\":0"
快速同步方法:
新建一个后缀.sql文件:mysql2redis_mission.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,
'missions' AS redis_key,
playerId AS hkey,
missionList AS hval
FROM TABLE_MISSION
) AS t
创建shell脚本mysql2redis_mission.sh
内容:
mysql GAME_DB --skip-column-names --raw < mission.sql | redis-cli --pipe
Linux系统终端执行该shell脚本或者直接运行该系统命令,即可将mysql数据库GAME_DB的表TABLE_MISSION数据同步到redis中键missions中去。mysql2redis_mission.sql文件就是将mysql数据的输出数据格式和redis的输入数据格式协议相匹配,从而大大缩短了同步时间。
经过测试,同样一份数据通过单条取出修改数据格式同步写入到redis消耗的时间为5min, 使用上面的sql文件和shell命令,同步完数据仅耗时3s左右。追问
这个文章我看过,脚本是php,我问的是python。
参考技术A import redisimport time
redis = redis.Redis(host='localhost', port=6379, db=0)
s_time = time.time()
with redis.pipeline() as pipe:
pipe.multi()
for index,item in item in enumerate(qset):#qset是你查询出来的结果集,
key = item['id']
value = item['name']
ret = pipe.sadd(key, value)
if index % 1000 == 0:
print "Now cnt: %d" % (i+1)
pipe.execute()
pipe.multi()
print "Execute..."
pipe.execute()
e_time = time.time()
上面省略了mysql查询代码,而且是以键值对来描述的
本回答被提问者和网友采纳mysql数据快速同步到redis
由于工作中有时需要把mysql的数据同步到redis,用python的redis库一条条塞进去太过耗时,查了下资料发现可以用redis协议快速实现。
一 . redis协议的格式:
比如
转换为redis协议格式则为:
二 . 通过linux命令行发送协议
# ‘–pipe’是利用了redis的管道传输,能极大的提升效率
# ‘|‘表示命令行管道符号,符号左侧的数据传入右侧作为参数
如果要将mysql数据导入redis,可以利用mysql语句拼凑出多条redis协议,再利用管道符号传给redis处理。
首先写好mysql语句,存入redis_protocol.sql中:
在命令行执行:
没有报错的话就可以了,再用redis-cli验证一下是否成功。我试过14万条数据导入只需一两秒,速度非常快。
三 . 附上一份python实现的代码
以上是关于使用python同步mysql到redis?由于数据较多,一条一条读出来写到redis太慢,有没有可以批量操作的。的主要内容,如果未能解决你的问题,请参考以下文章