大数据下Redis的应用1Redis客户端的区别1.1 redis普通客户端
目前,市场上最受欢迎的客户是杰迪丝,生菜和雷迪森。
使用
jedis客户端的连接模式是基于TCP阻塞模式。
生菜,莴苣
Uce是一种基于netty的复用异步无阻塞模式。
redisson
它比上面两种用得少。
当并发数量少的时候,它们的性能可能差不多,jedis的性能可能比莴笋好但当并发次数增加时,jedis的超时错误会增加,而莴苣只增加平均响应时间和最大响应时间,莴苣以稳定为主
1.2 epoll模型——为什么单线程的redis快。
redis采用epoll模型来提高链路处理能力。
传统TCP链路与epoll模型的本质区别。
TCP链路中的链路数量存在瓶颈伴随着连接数的增加,响应速度会明显变慢
Epoll可以支持更多数量的连接,而不会对性能产生重大影响。
2.大数据2.1分片模式下redis的存储方案。
分片模式是部署多个redis节点,然后由客户端决定数据分片规则常见的分片规则是根据节点数量对数据进行哈希处理
优势:
服务器不需要复杂的配置,路由规则由客户端决定。
缺点:
缺点很明显如果多个节点中的一个节点挂机,这部分数据会丢失,因为客户端仍然为每个节点分配一个连接,客户端在配置分片节点的IP时要注意
IP列表的顺序不能随意指定,IP变更也会影响数据,使得扩容相当麻烦。
建议:如果分片节点少,可以用分片适当分担压力。
示例:配置。
spring : remote : ecredi 3360 type :s hardinguri :—192 . 168 . 1 . 3:6379—192 . 168 . 1 . 433606379—192 . 168 . 1 . 533606379—192 . 168 . 1 . 4:6379 . 16192
伴随着Redis版本的推出,sentry的概念应运而生,sentry实现了自动故障恢复,不用担心IP是否改变。
优势:
哨兵模式以主从模式为基础,所有主从模式的优点都被哨兵模式所拥有。
主从可以自动切换,系统更加健壮,可用性更高。
Sentinel会不断检查主服务器和从服务器是否运行正常当受监控的Redis服务器出现问题时,Sentinel会通过API脚本向管理员或其他应用程序发送通知
缺点:
spring 3360 Redis : password :123456 sentinel : masternode : masternode : masternode : password :26379,47,98,47,98 . 21799999998
通过数据分片的方式解决数据共享的问题,同时提供数据复制和故障转移功能,包括哨兵模式的所有功能。
优点:数据按槽分散存储,任意片上的数据都可以通过访问任意主节点获得当任何一个主节点都可以扩展或者增加一个新的主节点时,数据会自动分片同步迁移,服务器不需要离线如果每个主机使用主从模式,当主机出现故障时,下面的从机将选出一个新的主机
缺点:需要ruby部署,配置相当麻烦,维护也不方便。
示例:配置。
spring : redis : password : cluster : node 3360192 . 168 . 1 .6379,192.168.1.4:6379,192 . 168 . 1 . 433:636
Cachecloud是一套解决方案,可以实现各种类型的自动部署,解决Redis实例的碎片化现象,提供完善的统计,监控和运维功能,降低运维成本和误操作,提高机器利用率,提供灵活的伸缩。
优势:
配置更简单,集群节点不再由客户端维护,节点列表可以通过配置域自动获取。
示例:配置。
应用案例:
2.5 redis存储方案选择。
:独立模式或切片模式,吞吐量较低,数据安全性较低。
:哨兵模式和集群模式,具有大吞吐量和高数据安全性。
:集群模式,吞吐量大,数据安全性高,扩展性强。
3.性能优化3.1日志优化。
Redis日志存储模式分为两种:RDB和AOFRDB是实时写入磁盘,AOF是延迟批处理写入磁盘
p>
RDB模式:
优点:实时存储日志,在数据恢复方面更有优势
缺点:磁盘IO比较频繁,会影响redis的吞吐能力
AOF模式:
优点:定时批量刷新日志到磁盘,适合高吞吐的场景,对redis性能影响较小
缺点:如果某一个时刻redis发生故障,可能会丢失内存中的数据,故障恢复的时候恢复不了这部分数据
模式选择:
如果吞吐量较小,使用RDB即可,吞吐量较大,可以选择AOF来提高性能,两种方式根据具体场景来选择
AOF配置:
appendonlyyes#aof文件名设置appendfilename"appendonly—$port.aof"#配置选择appendfsynceverysecdir/bigdiskpath#不开启aof重写,因为太消耗性能no—appendfsync—on—rewriteyes
AOF重写:分析当前redis中key对应的值来优化指令,来减少磁盘空间和压力,但因为需要判断合并逻辑,会有很大的性能开销,一般不开启aof重写
#假设服务器对键list执行了以下命令,127.0.0.1:6379gt,RPUSHlist"A""B"2127.0.0.1:6379gt,RPUSHlist"C"3127.0.0.1:6379gt,RPUSHlist"D""E"5127.0.0.1:6379gt,LPOPlist"A"127.0.0.1:6379gt,LPOPlist"B"127.0.0.1:6379gt,RPUSHlist"F""G"5127.0.0.1:6379gt,LRANGElist0—11)"C"2)"D"3)"E"4)"F"5)"G"127.0.0.1:6379gt,
正常AOF会把前面的6条写入命令都存入日志中,AOF重写会先去redis获取list的值,发现是,然后生成一条RPUSH list "C" "D" "E" "F" "G"来代替前面6条
3.2 缓存更新策略
redis默认情况下就是使用LRU策略的,因为内存是有限的,但是如果你不断地往redis里面写入数据,那肯定是没法存放下所有的数据在内存的
noeviction: 如果内存使用达到了maxmemory,client还要继续写入数据,那么就直接报错给客户端
allkeys—lru: 就是我们常说的LRU算法,移除掉最近最少使用的那些keys对应的数据(最常用的)
volatile—lru: 也是采取LRU算法,但是仅仅针对那些设置了指定存活时间(TTL)的key才会清理掉
allkeys—random: 随机选择一些key来删除掉
volatile—random: 随机选择一些设置了TTL的key来删除掉
volatile—ttl: 移除掉部分keys,选择那些TTL时间比较短的keys
除了LRU,还可以使用scan的方式进行轮询ttl的方式清理
3.3 代码中使用redis的一些建议
避免使用keys *这种模糊查询,会阻塞当前线程,使用scan的方式去处理,redis客户端建议不要使用redis desktop manager
Stringcursor=ScanParams.SCAN_POINTER_START,ScanParamsscanParams=newScanParams,//匹配表达式scanParams.match("key*"),//每次scan的条数scanParams.count(1000),while(true)ScanResultlt,lt,span=""gt,Stringgt,result=jedis.scan(cursor,scanParams),cursor=result.getStringCursor,if("0".equals(cursor))break,
hgetall也应该避免使用,使用hscan代替,但如果通过RedisTemplate回调的方式使用hscan应该注意资源的释放,否则会出现请求到达一定次数的时候就不能发起请求的问题
如果set的时候同时设置expire过期时间,不要先set再expire这种方式,应该使用原子操作
setkeyvalue(PXmilliseconds)(NX
对于同一个需求多次改版redis中写入不同格式的数据,会产生兼容性问题,可以使用type命令去处理兼容,然后监控等老数据不存在之后再把判断逻辑移除
Stringtype=jedis.type,if("string".equalsIgnoreCase(type))//dosomethingelseif("list".equalsIgnoreCase(type))//dosomething
如果redis中的数据需要做去重,可以使用set或hashmap,hashmap性能更高,但对于维护hashmap数据结构之外的数据比较多,之前测试过,100B的数据存放到hashmap,但实际占用量可能有200B~300B甚至更多,set对于数据多的情况下性能会低一点
建议:数据少的情况下用set,数据多就用hashmap,但要注意尽量减少存储内容的长度,比如"source":"order"可以改成"s":1
去重操作不建议使用list,因为每次判断都要从list中取数据然后再add进去,多线程操作下还是可能会出现重复问题
//在多线程模式下会有问题//假设线程A和线程B同时执行lrangeListlt,lt,span=""gt,Stringgt,list=jedis.lrange,if(!list.contains("bbb"))jedis.lpush("bbb"),
如果一次处理的命令很多,使用pipeline性能更好
list可以结合lpush/rpop,rpush/lpop来实现队列功能,但不建议把list当成是MQ的功能,因为没有记录的状态,无法跟踪数据处理情况
关于redis分布式锁,目前流行的实现方式还没有完美的方案,使用lua脚本的版本也不是完美的,如果需求允许延时或者一定时间内不允许执行多次,setnx设置过期时间是最好的方案
4,故障转移与数据迁移 4.1 数据迁移方案
老节点替换为新节点,新老key兼容处理
将新节点作为老节点的slave节点,等数据自动同步完成之后下架老节点,不建议使用代码迁移,因为不同业务数据结构可能很多
不同类型的节点之间迁移的方法不同,如果单节点迁移至分片集群只能借助迁移工具来完成
如果新业务将使用新的key,要保留旧key,可以开启两个连接池,一个处理新key,一个处理旧key,这样等旧key都失效的时候移除对旧key的连接就可以完全迁移到新key业务
动态扩容
必须在集群模式下才可以进行动态扩容,也可以使用cachecloud,数据会自动同步到各个节点
在数据迁移的过程中即使访问的某个key正在迁移,数据也是可以正常返回的,不用担心迁移过程会对数据访问造成影响
4.2 故障转移对于客户端的影响
redis集群模式虽然可以在某个master节点发生故障的时候自动从slave中选举节点当master,但类似jedis的客户端并不支持故障转移,也就是当集群某节点发生故障正在切换的时候,客户端如果正在访问故障节点,这时集群故障转移还没有完成,客户端会报错,如果需要让客户端也支持故障转移,需要修改jedis客户端源码来实现。
声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多企业信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。投资有风险,需谨慎。
9月6日上午,在崂山区政府西塔楼一楼大厅,崂山区科创委联合沙子口街道、大石社区启动了为期5天的大石村农民水彩画展。本次画
2021-09-08 12:23在5米高空作业,将数吨重的火车车轮或者小到几十斤的ldquo;铁疙瘩rdquo;安全装卸到位,可能谁也不会把这一切和一个
2021-09-03 11:10每个孩子都有其独特的成长规律。在孩子成长的过程中,每一步都充满着对这个世界的好奇,那作为家长的我们,该如何顺应孩子的成长
2021-08-30 18:502021年7月19日,备受关注的2021第五届中国家居品牌大会在广州启幕,现场发布2020-2021中国家居十大优选品牌
2021-07-26 01:28