Redis管道技术使用总结:
Redis服务是一种C/S模型,提供请求-响应式协议的TCP服务,所以当客户端请求发出,服务端处理并返回结果到客户端,一般是以阻塞形式等待服务端的响应,但这在批量处理连接时延迟问题比较严重,所以Redis为了提升或弥补这个问题,引入了管道技术:可以做到服务端未及时响应的时候,客户端也可以继续发送命令请求,做到客户端和服务端互不干涉影响,服务端并最终返回所有服务端的响应,这在促进原有C/S模型交互的响应速度上有了质的提高。
1、特点
在C/S交互中,客户端可发送任意数请求命令,不需要等服务端响应后再行发送请求;而服务端可以一次性完成并返回所有客户端请求结果,也可以分批次返回请求结果,这主要看服务端处理结果的速度而定。
2、语法
在构建批量命令集或是组装属性字符串时,命令间使用\r\n进行分离即可,例如:
SELECT CONCAT ('$',LENGTH(redis_key),'\r\n',redis_key,'\r\n')
3、验证
A、开启redis服务
$/redis/bin/redis-server /redis/etc/redis.conf
B、测试是否可用
$(echo -en "PING\r\n SET test redis\r\nGET test\r\nINCR visit\r\nINCR visit\r\nINCRvisit\r\n"; sleep 10) | nc localhost 6379
结果:
NOTE:
使用PONG命令测试本地服务使用连通;
使用SET/GET赋值和取值;
使用INCR三次为visit加1;
4、使用
这里举个实际使用例子:同步数据库数据到Redis缓存数据库,目的是为提高速度降低数据库的IO操作频次,以及降低服务器的压力,也就是我们常说的使用Redis缓存数据库需求(这里我们以Mysql数据库为例说明)。
A、新建t_user_info数据表
B、编写一转换json的lua
因为Redis 2.6已开始lua的解析支持,所以我们可以使用它来在倒入数据到Redis数据库过程中,实时转换从数据库读取的数据格式为json,这样方便后期程序拿到数据之后不需要再行编码解析直接使用即可(至于lua,这里不介绍,以避免偏离主题,后续博文会专门介绍它的使用细节),lua脚本内容如下:
for k,y in pairs(ok) do
for key,val in pairs(v) do
if key%2 ==0 then
tmp[v[key-1]] = v[key];
end
end
ret[k] = tmp;
end
ngx.say(cjson.encode(ret));
NOTE:
这里不介绍lua的相关内容,具体会在后续文章中介绍,请留意关注博客更新。
C、Redis与Mysql数据同步
首先,编写一个sql脚本:
SELECT CONCAT(
'*14\r\n',
'$',LENGTH(redis_cmd),'\r\n',redis_cmd,'\r\n',
'$',LENGTH(redis_key),'\r\n',redis_key,'\r\n',
'$',LENGTH(id_key),'\r\n',id_key,'\r\n','$',LENGTH(id_val),'\r\n',id_val,'\r\n',
'$',LENGTH(account_key),'\r\n',account_key,'\r\n','$',LENGTH(account_val),'\r\n',account_val,'\r\n',
'$',LENGTH(password_key),'\r\n',password_key,'\r\n','$',LENGTH(password_val),'\r\n',password_val,'\r\n',
'$',LENGTH(nickname_key),'\r\n',nickname_key,'\r\n','$',LENGTH(nickname_val),'\r\n',nickname_val,'\r\n',
'$',LENGTH(email_key),'\r\n',email_key,'\r\n','$',LENGTH(email_val),'\r\n',email_val,'\r\n',
'$',LENGTH(address_key),'\r\n',address_key,'\r\n','$',LENGTH(address_val),'\r\n',address_val,'\r'
)
FROM(
SELECT
'HMSET' AS redis_cmd,CONCAT(account,password,'_hash') AS redis_key,
'id' AS id_key,id AS id_val,
'account' AS account_key,account AS account_val,
'password' AS password_key,password AS password_val,
'nickname' AS nickname_key,nickname AS nickname_val,
'email' AS email_key,email AS email_val,
'address' AS address_key,address AS address_val
FROM t_user_info
) AS t
其次,执行同步操作指令:
$mysql –h 127.0.0.1 –uroot –Dcwteam --skip-column-names --raw <
/redis/sql/mysql_to_redis.sql | redis-cli –eval
/redis/lua/redis_table_json.lua --pipe
最后,查看同步是否正常:
D、结果查看
$/redis/bin/redis-cli -p 6379
127.0.0.1:6379>hgetall cwteame10adc3949ba59abbe56e057f20f883e_hash
由上图已经说明,我们的数据同步正常,而且在Redis中每个key对应了数据库中的一条记录,所以这个可以在高用户量时,缓存用户数据提高登录速度。
NOTE:
cwteame10adc3949ba59abbe56e057f20f883e_hash:
代表key为account+password+_hash组合的键名字;
5、注意
A、同步Mysql数据到Redis中缓存
需要保证Redis中的数据与Mysql中一致,虽然不一致的时候会从数据库中获得,但是就浪费了Redis的资源优势。
建议:使用定时机制,定期同步数据;
B、Mysql数据在Redis中结构关系
Redis是非关系行数据存储结构,所以需要建立Mysql中的多个关联表到Redis中的存储结构关系规则,目的只为方便找到关联数据内容。