2019-11-29

大key如何发现及治理?

发现

redis4.0之前

  1. redis-cli --bigkeys命令。可以找到某个实例5种数据类型(String、hash、list、set、zset)的最大key。

优点是可以在线扫描(用scan命令通过游标遍历键空间并且在生产上可以通过对slave执行该命令),不阻塞服务;缺点是信息较少,内容不够精确。扫描结果中只有string类型是以字节长度为衡量标准的。List、set、zset等都是以元素个数作为衡量标准,元素个数多不能说明占用内存就一定多。

  1. 自定义的扫描脚本,通过strlen、hlen、scard等命令获取字节大小或者元素个数。这样获取的到和上述1缺点一样,不能获取到除string类型外的具体字节长度等内存信息。

  2. debug object key命令。可以查看某个key序列化后的长度,每次只能查找单个key的信息。(元素个数较多的数据结构,debug object执行速度比较慢,存在阻塞Redis的可能,所以不推荐)。

  3. 通过了解rdb文件结果,通过工具解析rdb文件,分析rdb文件,来获取大key,网上的redis-rdb-tools,godis-cli-bigkey等。redis实例上执行bgsave,然后对dump出来的rdb文件进行分析,找到其中的大KEY。

redis4.0之后

memory usage key命令

采用抽样估算整个key的内存大小(比如hash类型有100个field,只抽取5个(默认值)来估算整个的内存)样本的数量决定了key的内存大小的准确性和计算成本,样本越大,循环次数越多,计算结果更精确,性能消耗也越多。可以通过SAMPLES参数设置样本大小

我们可以通过脚本在集群低峰时扫描Redis,循环去获取所有key的内存大小。

治理

redis monitor

  1. 客户端通过执行MONITOR命令可以将自己变为一个监视器,实时地接受并打印出服务器当前处理的命令请求的相关信息,如下图


    image1.png

此时,当其他客户端向服务器发送一条命令请求时,服务器除了会处理这条命令请求之外,还会将这条命令请求的信息发送给所有监视器:


image2.png

2.原理

  • redisServer维护一个monitors的链表,记录自己的监视器,每次收到MONITOR命令之后,只需将客户端追加到表尾即可
  • 向监视器传播命令

call函数中有对于监视器命令传播,将命令打包为协议,发送给监视器

详情参考:https://www.jianshu.com/p/36420adb344b

本地缓存 - 通知机制怎么实现的?

Redis键通知机制

自从redis2.8以后出了一个新特性,Keyspace Notifications 称为“键空间通知”。

这个特性大概是,凡是实现了Redis的Pub/Sub的客户端,只需要订阅相应Channel,就可以获得对Key操作的一些事件,从而可以处理一些业务。

比如:

  1. 当你del一个key时,就可以触发一个del事件通知。
  2. 一个key的失效时间到了,就会触发expire事件通知。
  3. 对一个库所有key操作,都可以获取通知。

注意事项:

1)因为 Redis 目前的订阅与发布功能采取的是发送即忘(fire and forget)策略, 所以是不可靠的,并不能确保消息送达。

2)Redis Pub/Sub 是一种并不可靠地消息机制,他不会做信息的存储,只是在线转发,那么肯定也没有ack确认机制,另外只有订阅段监听时才会转发!所以Keyspace Notification 也不是可靠地通知系统

本地缓存的应用

键通知机制通过发布订阅实现,具体步骤如下:
1.修改配置:键空间通知功能耗费CPU,默认关闭,需要修改配置文件redis.conf或 操作CONFIG SET命令,设置notify-keyspace-events选项,来启用或关闭该功能(耗费cpu)。
2.对Redis实例进行发布订阅,指定监听类和监听事件类型(键删除,过期);
3.监听类继承JedisPubSub,实现相应操作(清除本地缓存,保证一致性);
4.客户端进行操作,以触发订阅事件发生。

image.png

参数:


image.png

代码实现:

import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;

public class Subscriber {

    public static void main(String[] args) {
        JedisPool pool = new JedisPool(new JedisPoolConfig(), "127.0.0.1", 3069);

        Jedis jedis = pool.getResource();
        config(jedis);

        jedis.psubscribe(new KeyExpiredListener(), "__key*__:*");
    }
    private static void config(Jedis jedis){
        String parameter = "notify-keyspace-events";
        List<String> notify = jedis.configGet(parameter);

        if(notify.get(1).equals("")){
            jedis.configSet(parameter, "KA");//参数意义见上图。
        }
    }
}
class KeyExpiredListener extends JedisPubSub {


    @Override
    public void onPSubscribe(String pattern, int subscribedChannels) {
        System.out.println("onPSubscribe " + pattern + " " + subscribedChannels);
    }
  // 取得订阅的消息后的处理  (key过期可以删除本地缓存)
    @Override
    public void onPMessage(String pattern, String channel, String message) {
       // 删除本地缓存
    }
}

附:redis文件事件原理:

Redis中的文件事件关注网络IO,用于处理 Redis 服务器和客户端之间的网络IO。

Redis基于Reactor模式开发了自己的网络事件处理器,也就是文件事件处理器。文件事件处理器使用IO多路复用技术,同时监听多个套接字,并为套接字关联不同的事件处理函数。当套接字的可读或者可写事件触发时,就会调用相应的事件处理函数。
如下图所示,文件事件处理器有四个组成部分,它们分别是套接字、I/O多路复用程序、文件事件分派器以及事件处理器,如下图所示:


image.png

文件事件每当一个套接字准备好执行 accept、read、write和 close 等操作时,就会产生一个文件事件。因为 Redis 通常会连接多个套接字,所以多个文件事件有可能并发的出现。

I/O多路复用程序负责监听多个套接字,并向文件事件派发器传递那些产生了事件的套接字。

尽管多个文件事件可能会并发地出现,但I/O多路复用程序总是会将所有产生的套接字都放到同一个队列(也就是后文中描述的aeEventLoop的就绪事件表)里边,然后文件事件处理器会以有序、同步、单个套接字的方式处理该队列中的套接字,也就是处理就绪的文件事件。


image.png

所以,一次 Redis 客户端与服务器进行连接并且发送命令的过程如上图所示。

1.客户端向服务端发起建立 socket 连接的请求,那么监听套接字将产生 AE_READABLE 事件,触发连接应答处理器执行。处理器会对客户端的连接请求进行应答,然后创建客户端套接字,以及客户端状态,并将客户端套接字的 AE_READABLE 事件与命令请求处理器关联。
2.客户端建立连接后,向服务器发送命令,那么客户端套接字将产生 AE_READABLE 事件,触发命令请求处理器执行,处理器读取客户端命令,然后传递给相关程序去执行。
3.执行命令获得相应的命令回复,为了将命令回复传递给客户端,服务器将客户端套接字的 AE_WRITEABLE 事件与命令回复处理器关联。当客户端试图读取命令回复时,客户端套接字产生 AE_WRITEABLE 事件,触发命令回复处理器将命令回复全部写入到套接字中。
具体源码参考:https://www.cnblogs.com/jabnih/p/4746138.html

SDK端统计分析热Key

image.png

说明:
1.业务方应用发起执行命令;
2.sdk首先判断是否是热key,是的话从热key模块中获取信息,否则执行正常redis命令执行流程,并异步上报命令信息到热key分析系统,对于expire,del命令也会上报到分析系统,分析系统会通知sdk中的热key模块,执行对应的删除操作,到达数据的一致性;
3.热key分析系统:

  • 不断收集来自各个应用的sdk端的命令信息
  • 自身维护一个热key列表,每隔5秒分析一次当前命令产生的热key,并下发给对应的应用程序。
  • 当分析系统收到key失效的命令时,立即下发失效通知到sdk端热key模块,保持数据的一致性。
    以上就是整个sdk端发现处理热key的大概思路。

Encache和guava cache的区别

guava cache

GuavaCache 提供了一般我们使用缓存所需要的几乎所有的功能,主要有:

  • 自动将entry节点加载进缓存结构中;
  • 当缓存的数据已经超过预先设置的最大值时,使用LRU算法移除一些数据;
  • 具备根据entry节点上次被访问或者写入的时间来计算过期机制
    (无读写回收expireAfterAccess,无更新回收expireAfterWrite,上次操作时间后再刷新refreshAfterAccess);
  • 缓存的key被封装在WeakReference引用内;
  • 缓存的value被封装在WeakReference或者SoftReference引用内;
  • 移除entry节点,可以触发监听器通知事件(同步,异步);
  • 统计:统计缓存使用过程中命中率/异常率/未命中率等数据。

Guava Cache其核心数据结构大体上和ConcurrentHashMap一致,具体细节上会有些区别。功能上,ConcurrentMap会一直保存所有添加的元素,直到显式地移除.相对地,Guava Cache为了限制内存占用,通常都设定为自动回收元素.在某些场景下,尽管它不回收元素,也是很有用的,因为它会自动加载缓存.
Guava Cache 官方推荐的使用场景:
1.愿意消耗一些内存空间来提升速度;
2.能够预计某些key会被查询一次以上;
3.缓存中存放的数据总量不会超出内存容量(Guava Cache是单个应用运行时的本地缓存)。

Ehcache

特点:

  • 提供内存和磁盘存储,缓存在内存和磁盘存储可以伸缩到数G;
  • 过期策略(LRU、LFU和FIFO缓存淘汰算),也可以自定义,每个Cache的存活时间都是可以设置和控制的
  • 动态、运行时缓存配置,存活时间、空闲时间、内存和磁盘存放缓存的最大数目都是可以在运行时修改的。
  • 持久化,在VM重启后,持久化到磁盘的存储可以复原数据。
  • 缓存管理器监听器,可以监听Removed/Put/Updated/Expired 事件
  • JMX功能,可以监控和管理如下的MBean:CacheManager、Cache、CacheConfiguration、CacheStatistics
  • 分布式缓存,通过RMI、JGroups或JMS进行的异步或同步的缓存复制
  • 多种配置模式,配置文件、声明式配置、编程式配置,甚至通过指定构造器的参数来完成配置

[图片上传中...(image.png-451bd3-1575192572195-0)]

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容