赞
踩
目录
3.2、MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据
6.1.1、合理选择合适的数据结构、回收策略、过期时间、持久化配置
6.1.4、使用Kubernetes 的监测工具,监控各种性能参数
6.2.2、开启 慢日志并分析(或Kubernetes分析)
Redis有多快?单机可以支持约10w/s的QPS。
(1)纯内存操作
(2)5中数据类型选用的内部数据结构经过精心设计
(3)6.0以前采用单线程,省去了很多上下文切换的时间以及CPU消耗,不存在竞争条件,不用去考虑各种锁的问题
(4)基于非阻塞IO多路复用机制(select()、epoll())
通过一个线程监听多个socket的IO连接事件,从而实现在单个线程中处理多个连接的读写操作
这个线程是一个事件处理器(event loop);
该事件处理器会将每个连接对应的 文件描述符 注册到事件监听机制中,并在事件就绪时调用相应的读写函数来处理IO操作,这样就可以单线程处理多个连接IO操作
redis采用的是定期删除+惰性删除策略。
定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下尤其不适用。
(1)定期删除,redis默认每个100ms检查,检查有过期key则删除。
需要说明的是,redis不是每隔100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。
(2)于是,惰性删除派上用场。在获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了,如果过期了此时就会删除(懒汉式)。
不是的,如果定期删除没删除key,也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。在redis.conf中配置。
当Redis的内存使用达到配置的最大内存限制时,会触发内存淘汰机制来释放部分内存空间
(1)allkeys-lru(推荐)
当内存不足以容纳新写入数据时,移除最近最少使用的key
(2)allkeys-random(不推荐)
随机移除某个key
(3)volatile-lru(不推荐)
在设置了过期时间的键空间中,移除最近最少使用的key
(4)volatile-random(不推荐)
在设置了过期时间的键空间中,随机移除某个key
(5)volatile-ttl(不推荐)
(1)事务
通过使用MULTI、EXEC和WATCH命令,可以将多个操作作为一个事务进行执行,但是生产环境redis一般是集群的,不适用。
(2)乐观锁
使用版本号(Version)来实现乐观锁。每次对键进行修改时,都会更新该键的版本号;在读取时,先获取当前版本号,然后进行操作,最后再次验证版本号是否一致,如果版本号不一致,说明该键已被其他客户端修改,需要重新尝试。
(3)分布式锁(推荐)
是一种在分布式系统中解决并发竞争的常见机制,可使用Redisson
(4)队列Queue
将需要对同一个键进行操作的请求放入队列中,然后通过一个单独的线程或来处理队列中的请求。这样可以保证对同一个键的操作按序执行,避免并发竞争。
(1)缓存淘汰策略
redis 内存大小上升到一定大小时,就会施行数据淘汰策略,可选LRU最近最少使用淘汰策略;
(2)数据预热
在系统启动时,将热点数据预先加载到Redis中。可以使用jedis的管道(Pipeline )批量初始化加载到Redis。
- Jedis jedis = JedisUtil.getJedis();
- // 管道
- Pipeline pipelined = jedis.pipelined();
-
- for (int i = 0; i < 10000; i++) {
- pipelined.set("cc_"+i, i+"");
- }
- //执行管道中的命令
- pipelined.sync();
(1)memcached只支持字符串,redis支持更为丰富的数据类型
(2)redis的速度比memcached快很多
(3)redis可以持久化数据到磁盘,memcached只能存在内存中
优先顺序:本地内存(咖啡因)-->redis(回填内存)--->数据库(回填内存、redis)
将用户会话信息存储在Redis中,实现分布式会话管理
list/set的lpush/rpop实现消息队列。
(1)将消息推入队列
使用lpush命令将消息推入队列的左侧(头部);
(2) 队列中取出消息
使用rpop命令从队列的右侧(尾部)弹出消息,List结构的话可实现先进先出的消息处理。
实现消息队列中list和set区别:
(1)常见排行榜需求
(2)实现原理(Sorted Set)
有序集合(Sorted Set)中的每个元素都有一个分值(score),可根据分值进行排序。
因此,我们可以将用户或商品的得分作为有序集合中的分值,将用户或商品的唯一标识作为有序集合中的成员。
(3)具体实现
(1)String可变字符串实现
incry指令增加计数器的值
- Jedis jedis = new Jedis("localhost");
- // 存储计数值
- jedis.set("counter", "0");
- // 增加计数值
- jedis.incrBy("counter", 5);
- // 获取计数值
- String counterValue = jedis.get("counter");
(2)Redisson的RAtomicLong原子类 实现
- RedissonClient redisson = Redisson.create(config);
- // 获取或创建计数器对象
- RAtomicLong counter = redisson.getAtomicLong("counter");
- counter.incrementAndGet(); // 增加计数值1
- long counterValue = counter.get(); // 获取计数值
性能瓶颈:内存、网络贷款、CPU、持久化配置、锁竞争、阻塞操作、数据结构选择
避免存储不必要的数据、大型数据。可通过压缩数、设置过期策略实现
批量操作或者数据预热时,使用java的客户端Jedis的Pipeline管道机制(redis没有该命令但是Jedis有)。
(1)监控系统
(2)慢查询日志
(3)内存分析
使用info命令来查看内存使用情况,包括内存占用情况、内存碎片、内存淘汰策略。
(4)配置分析、网络分析、命中率分析
config配置开启慢日志记录,例如设置阈值为5则保利最近500条记录。
可查看哪些命令执行耗时、哪些频繁、哪些消耗资源多。
(1) 立即停止写入操作
(2)检查持久化配置、分析原因
(3)手动持久化
RDB失败,手动执行SAVE或BGSAVE命令来进行持久化;AOF失败,手动执行BGREWRITEAOF生成新AOF
(4)数据备份和恢复
(5)数据一致性检查
(6)定期备份、监控报警
(1)命令bigkeys(4.0)、SCAN扫描大键
(2)分析大键类型
根据扫描结果,确定大键的类型,是字符串、哈希、列表、集合还是有序集合等
(3)GET命令查看大键的具体数据
(4)分析大建产生原因、优化存储数据结构
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。