Comment résoudre le problème de raccourci clavier dans Redis ? L'article suivant vous présentera les solutions courantes au problème des touches de raccourci du cache Redis. J'espère qu'il vous sera utile !
Lorsqu'on fait des affaires côté C, il est inévitable d'introduire un cache de premier niveau pour remplacer la pression de la base de données et réduire le temps de réponse de l'entreprise. En fait, chaque fois qu'un middleware est introduit pour résoudre le problème. , cela entraînera inévitablement de nombreux nouveaux problèmes qui nécessitent une attention particulière, tels que la manière d'assurer la cohérence du cache mentionnée dans l'article précédent « Cohérence des bases de données et du cache en pratique ». En fait, il y aura d'autres problèmes, tels que des touches de raccourci, des touches volumineuses, etc. qui peuvent survenir lors de l'utilisation de Redis comme cache de premier niveau. Dans cet article, nous aborderons la question des hot touches<.> et comment le rendre raisonnable. Résolvez le problème de la <code>raccourci clavier
. -
Contexte
热key(hot key)
问题来讨论,如何合理的解决
热key
问题。
背景
热key
是什么问题,如何导致的?
一般来说,我们使用的缓存Redis都是多节点的集群版,对某个key进行读写时,会根据该key的hash计算出对应的slot,根据这个slot就能找到与之对应的分片(一个master和多个slave组成的一组redis集群)来存取该K-V。但是在实际应用过程中,对于某些特定业务或者一些特定的时段(比如电商业务的商品秒杀活动),可能会发生大量的请求访问同一个key。所有的请求(且这类请求读写比例非常高)都会落到同一个redis server上,该redis的负载就会严重加剧,此时整个系统增加新redis实例也没有任何用处,因为根据hash算法,同一个key的请求还是会落到同一台新机器上,该机器依然会成为系统瓶颈2,甚至造成整个集群宕掉,若此热点key的value 也比较大,也会造成网卡达到瓶颈,这种问题称为 “热key” 问题。【相关推荐:Redis视频教程】
如下图1、2所示,分别是正常redis cluster集群和使用一层proxy代理的redis 集群key访问。
如上所说,热key会给集群中的少部分节点带来超高的负载压力,如果不正确处理,那么这些节点宕机都有可能,从而会影响整个缓存集群的运作,因此我们必须及时发现热key、解决热key问题。
1.热key探测
热key探测,看到由于redis集群的分散性以及热点key带来的一些显著影响,我们可以通过由粗及细的思考流程来做热点key探测的方案。
1.1 集群中每个slot的qps监控
热key最明显的影响是整个redis集群中的qps并没有那么大的前提下,流量分布在集群中slot不均的问题,那么我们可以最先想到的就是对于每个slot中的流量做监控,上报之后做每个slot的流量对比,就能在热key出现时发现影响到的具体slot。虽然这个监控最为方便,但是粒度过于粗了,仅适用于前期集群监控方案,并不适用于精准探测到热key的场景。
1.2 proxy的代理机制作为整个流量入口统计
如果我们使用的是图2的redis集群proxy代理模式,由于所有的请求都会先到proxy再到具体的slot节点,那么这个热点key的探测统计就可以放在proxy中做,在proxy中基于时间滑动窗口
,对每个key做计数,然后统计出超出对应阈值的key。为了防止过多冗余的统计,还可以设定一些规则,仅统计对应前缀和类型的key。这种方式需要至少有proxy的代理机制,对于redis架构有要求。
1.3 redis基于LFU的热点key发现机制
redis 4.0以上的版本支持了每个节点上的基于LFU的热点key发现机制,使用redis-cli –hotkeys
即可,执行redis-cli时加上–hotkeys选项。可以定时在节点中使用该命令来发现对应热点key。
如下所示,可以看到redis-cli –hotkeys
Hot Key
Comment est-ce causé ?
🎜 De manière générale, le cache Redis que nous utilisons est une version de cluster multi-nœuds lors de la lecture et de l'écriture d'une certaine clé, l'emplacement correspondant sera calculé en fonction du hachage de la clé, et l'emplacement correspondant pourra être trouvé sur cette base. L'emplacement Sharding (un ensemble de clusters Redis composé d'un maître et de plusieurs esclaves) est utilisé pour accéder au K-V. Cependant, dans le processus de demande proprement dit, pour certaines entreprises spécifiques ou certaines périodes de temps spécifiques (telles que les activités de vente flash de produits dans les entreprises de commerce électronique), un grand nombre de demandes peuvent survenir pour accéder à la même clé. Toutes les requêtes (et le taux de lecture-écriture de ces requêtes est très élevé) tomberont sur le même serveur Redis, et la charge sur Redis sera considérablement augmentée. À ce stade, l'ajout de nouvelles instances Redis à l'ensemble du système sera important. cela ne sert à rien, car selon l'algorithme de hachage, les demandes pour la même clé tomberont toujours sur la même nouvelle machine, ce qui deviendra toujours le goulot d'étranglement du système2, et provoquera même le crash de l'ensemble du cluster si la valeur de cette clé de hotspot est relativement élevée. grand, cela entraînera également que la carte réseau atteigne le goulot d'étranglement. Ce problème est connu sous le nom de problème de « touche de raccourci ». [Recommandations associées :
Tutoriel vidéo Redis]🎜🎜 Comme le montrent les figures 1 et 2 ci-dessous, respectivement, se trouvent l'accès normal au cluster de cluster Redis et à la clé de cluster Redis à l'aide d'une couche d'agent proxy. 🎜🎜
🎜🎜🎜🎜 Comme mentionné ci-dessus, Les touches de raccourci apporteront une pression de charge ultra-élevée à un petit nombre de nœuds du cluster. S'ils ne sont pas gérés correctement, ces nœuds peuvent tomber en panne, ce qui affectera le fonctionnement de l'ensemble du cluster de cache. Par conséquent, nous devons découvrir les touches de raccourci à temps. et résolvez-les. 🎜
1. Détection des touches de raccourci
🎜 Détection des touches de raccourci, constatant des impacts significatifs dus à la dispersion du cluster Redis et de la touche de raccourci, nous pouvons utiliser la méthode grossière Réfléchissez bien. sur le processus pour proposer une solution de détection de clé de point d'accès. 🎜
1.1 Surveillance QPS de chaque emplacement du cluster
🎜 L'impact le plus évident du raccourci clavier est que le QPS dans l'ensemble du cluster Redis n'est-ce pas ? En partant du principe que le trafic est inégalement réparti entre les emplacements du cluster, la première chose à laquelle nous pouvons penser est de surveiller le trafic dans chaque emplacement. Après avoir signalé le trafic, comparez le trafic dans chaque emplacement, puis le trafic. La touche de raccourci apparaîtra lors de la découverte des emplacements spécifiques concernés. Bien que cette surveillance soit la plus pratique, la granularité est trop grossière. Elle ne convient qu'aux premières solutions de surveillance de cluster et ne convient pas aux scénarios dans lesquels les touches de raccourci sont détectées avec précision. 🎜
1.2 Le mécanisme proxy est utilisé comme statistiques complètes d'entrée de trafic
🎜 Si nous utilisons le mode proxy du cluster Redis dans la figure 2, En raison de toutes les demandes, elles seront d'abord envoyées au proxy, puis au nœud de slot spécifique. Ensuite, les statistiques de détection de cette touche de raccourci peuvent être effectuées dans le proxy, en fonction de la
fenêtre glissante
, comptez chaque clé, puis comptez les clés qui dépassent le seuil correspondant. Afin d'éviter trop de statistiques redondantes, vous pouvez également définir certaines règles pour ne compter que les clés correspondant au préfixe et au type. Cette méthode nécessite au moins un mécanisme proxy et présente des exigences pour l'architecture Redis. 🎜
Mécanisme de découverte de clé de point d'accès basé sur LFU Redis 1.3
🎜 Les versions supérieures à Redis 4.0 prennent en charge les points d'accès basés sur LFU sur chaque nœud Pour la découverte de clé mécanisme, utilisez
redis-cli –hotkeys
. Ajoutez l'option –hotkeys lors de l'exécution de redis-cli. Vous pouvez utiliser cette commande régulièrement sur le nœud pour découvrir la clé de hotspot correspondante. 🎜🎜
🎜🎜 comme suit Comme le montre la figure, vous pouvez voir les résultats de l'exécution de
redis-cli –hotkeys
et les informations statistiques des touches de raccourci. Le temps d'exécution de cette commande est long et vous pouvez configurer une exécution planifiée. pour collecter des statistiques. 🎜
1.4 Détection basée sur le client Redis
Étant donné que les commandes Redis sont émises par le client à chaque fois, sur cette base, nous pouvons effectuer un comptage statistique dans certains codes du client Redis, et chaque client effectue des statistiques basées sur la fenêtre temporelle glissante, après avoir dépassé un certain seuil, il est signalé au serveur, puis le serveur l'envoie uniformément à chaque client et le délai d'expiration correspondant est configuré.
Cette méthode semble plus belle, mais en fait elle n'est pas si adaptée dans certains scénarios d'application, car la modification côté client apportera une plus grande surcharge de mémoire au processus en cours. Plus directement, les langages avec gestion automatique de la mémoire tels que. Java et goLang créeront des objets plus fréquemment, déclenchant gc et entraînant une augmentation du temps de réponse de l'interface. C'est quelque chose qui n'est pas facile à prédire. 优美
,其实在一些应用场景中并不是那么合适,因为在client端这一侧的改造,会给运行的进程带来更大的内存开销,更直接的来说,对于Java和goLang这种自动内存管理的语言,会更加频繁的创建对象,从而触发gc导致接口响应耗时增加的问题,这个反而是不太容易预料到的事情。
最终可以通过各个公司的基建,做出对应的选择。
2.热key解决
通过上述几种方式我们探测到了对应热key或者热slot,那么我们就要解决对应的热key问题。解决热key也有好几种思路可以参考,我们一个一个捋一下。
2.1 对特定key或slot做限流
一种最简单粗暴的方式,对于特定的slot或者热key做限流,这个方案明显对于业务来说是有损的,所以建议只用在出现线上问题,需要止损的时候进行特定的限流。
2.2 使用二级(本地)缓存
本地缓存也是一个最常用的解决方案,既然我们的一级缓存扛不住这么大的压力,就再加一个二级缓存吧。由于每个请求都是由service发出的,这个二级缓存加在service端是再合适不过了,因此可以在服务端每次获取到对应热key时,使用本地缓存存储一份,等本地缓存过期后再重新请求,降低redis集群压力。以java为例,guavaCache就是现成的工具。以下示例:
//本地缓存初始化以及构造
private static LoadingCache<String, List<Object>> configCache
= CacheBuilder.newBuilder()
.concurrencyLevel(8) //并发读写的级别,建议设置cpu核数
.expireAfterWrite(10, TimeUnit.SECONDS) //写入数据后多久过期
.initialCapacity(10) //初始化cache的容器大小
.maximumSize(10)//cache的容器最大
.recordStats()
// build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
.build(new CacheLoader<String, List<Object>>() {
@Override
public List<Object> load(String hotKey) throws Exception {
}
});
//本地缓存获取
Object result = configCache.get(key);
本地缓存对于我们的最大的影响就是数据不一致的问题,我们设置多长的缓存过期时间,就会导致最长有多久的线上数据不一致问题,这个缓存时间需要衡量自身的集群压力以及业务接受的最大不一致时间。
2.3 拆key
如何既能保证不出现热key问题,又能尽量的保证数据一致性呢?拆key也是一个好的解决方案。
我们在放入缓存时就将对应业务的缓存key拆分成多个不同的key。如下图所示,我们首先在更新缓存的一侧,将key拆成N份,比如一个key名字叫做"good_100",那我们就可以把它拆成四份,"good_100_copy1"、"good_100_copy2"、"good_100_copy3"、"good_100_copy4",每次更新和新增时都需要去改动这N个key,这一步就是拆key。
对于service端来讲,我们就需要想办法尽量将自己访问的流量足够的均匀,如何给自己即将访问的热key上加入后缀。几种办法,根据本机的ip或mac地址做hash,之后的值与拆key的数量做取余,最终决定拼接成什么样的key后缀,从而打到哪台机器上;服务启动时的一个随机数对拆key的数量做取余。
2.4 本地缓存的另外一种思路 配置中心
对于熟悉微服务配置中心的伙伴来讲,我们的思路可以向配置中心的一致性转变一下。拿nacos来举例,它是如何做到分布式的配置一致性的,并且相应速度很快?那我们可以将缓存类比配置,这样去做。
长轮询
+本地化
Au final, vous pouvez faire des choix correspondants à travers l'infrastructure de chaque entreprise. 🎜
2. Solution de raccourci clavier
🎜 Grâce aux méthodes ci-dessus, nous avons détecté la touche de raccourci ou l'emplacement de raccourci correspondant, nous devons alors résoudre le problème de touche de raccourci correspondant. Il existe plusieurs idées pour résoudre les raccourcis clavier. Passons-les une par une. 🎜
🎜2.1 Limiter le flux de touches ou d'emplacements spécifiques🎜🎜🎜 Le moyen le plus simple et le plus grossier est de limiter le flux d'emplacements ou de touches de raccourci spécifiques. Cette solution est évidemment bénéfique pour le. entreprise Il entraîne des pertes, il est donc recommandé de n'utiliser une limitation de courant spécifique qu'en cas de problème en ligne et que la perte doit être stoppée. 🎜🎜2.2 Utiliser le cache de deuxième niveau (local) 🎜🎜🎜 Le cache local est également la solution la plus couramment utilisée. Puisque notre cache de premier niveau ne peut pas résister à une pression aussi énorme, nous. Ajoutez un cache de deuxième niveau. Puisque chaque requête est émise par le service, il est parfait d'ajouter ce cache de deuxième niveau côté service. Par conséquent, chaque fois que le serveur obtient la touche de raccourci correspondante, il peut utiliser le cache local pour stocker une copie jusqu'au cache local. expire. Puis demandez à nouveau de réduire la pression sur le cluster Redis. En prenant Java comme exemple, guavaCache est un outil prêt à l'emploi. L'exemple suivant : 🎜rrreee🎜 Le plus grand impact du cache local sur nous est le problème d'incohérence des données. La durée pendant laquelle nous définissons le délai d'expiration du cache entraînera le problème d'incohérence des données en ligne le plus long. Ce temps de cache doit mesurer sa propre pression de cluster. et le temps d'incohérence maximum accepté par l'entreprise. 🎜🎜2.3 Suppression de clé🎜🎜🎜 Comment s'assurer qu'aucun problème de raccourci clavier ne se produira tout en garantissant autant que possible la cohérence des données ? Retirer la clé est également une bonne solution. 🎜🎜 Lorsque nous la mettons dans le cache, nous divisons la clé de cache de l'entreprise correspondante en plusieurs clés différentes. Comme le montre la figure ci-dessous, nous divisons d'abord la clé en N parties du côté du cache de mise à jour. Par exemple, si une clé est nommée "good_100", nous pouvons la diviser en quatre parties, "good_100_copy1", "good_100_copy2". ", " good_100_copy3 ", " good_100_copy4 ", ces N clés doivent être modifiées à chaque fois qu'elles sont mises à jour ou ajoutées. Cette étape consiste à supprimer la clé. 🎜🎜 Pour le côté service, nous devons trouver des moyens de rendre le trafic auquel nous accédons encore suffisamment, et comment ajouter des suffixes aux touches de raccourci auxquelles nous sommes sur le point d'accéder. Il existe plusieurs façons d'effectuer un hachage basé sur l'adresse IP ou MAC de la machine, puis de prendre le reste de la valeur et le nombre de clés partagées, et enfin de décider dans quel type de suffixe de clé est intégré, de sorte à quelle machine il sera touché ; un au démarrage du service. Le nombre aléatoire est le reste du nombre de clés partagées. 🎜🎜🎜🎜2.4 Une autre façon de penser le centre de configuration du cache local🎜🎜🎜 Pour ceux qui connaissent le centre de configuration des microservices, notre réflexion peut s'orienter vers la cohérence du centre de configuration. Prenons l'exemple de nacos. Comment parvient-il à assurer la cohérence de la configuration distribuée et à répondre rapidement ? Ensuite, nous pouvons comparer l'analogie du cache à la configuration et procéder comme ceci. 🎜🎜 Interrogation longue
+Localisation
configuration. Tout d'abord, toutes les configurations seront initialisées au démarrage du service, puis une longue interrogation sera lancée régulièrement pour vérifier si la configuration actuelle de surveillance du service a changé. En cas de changement, la longue demande d'interrogation reviendra immédiatement pour mettre à jour la configuration locale ; s'il n'y a aucun changement, pour Tous les codes métier, utilisez la configuration du cache mémoire local. Cela garantit la rapidité et la cohérence de la configuration du cache distribué. 🎜2.5 Autres plans qui peuvent être élaborés à l'avance
Chacune des solutions ci-dessus est relativement indépendante pour résoudre le problème des touches de raccourci, donc si nous sommes vraiment confrontés aux demandes commerciales, nous aurons en fait beaucoup de temps pour réfléchir à la conception globale de la solution . Pour les problèmes de raccourci provoqués par certains scénarios de ventes flash extrêmes, si nous disposons d'un budget suffisant, nous pouvons directement isoler l'activité de services et le cluster de cache Redis pour éviter d'affecter les activités normales, et en même temps, nous pouvons temporairement adopter une meilleure reprise après sinistre et Mesures limitatives actuelles.
Quelques solutions intégrées
Il existe déjà de nombreuses solutions relativement complètes au niveau des applications pour hotKey sur le marché. Parmi elles, JD.com dispose d'un outil de raccourci open source à cet égard, le principe est de fournir des informations sur le client. côté, puis signaler le raccourci clavier de réponse, une fois que le serveur l'a détecté, il enverra le raccourci clavier correspondant au serveur correspondant pour la mise en cache locale, et ce cache local sera mis à jour de manière synchrone après la mise à jour de la clé correspondante distante. solution à l'heure actuelle, 自动探测热key、分布式一致性缓存
JD Retail Hot key.
Résumé
Ci-dessus sont quelques solutions sur la façon de gérer les touches de raccourci que l'auteur a approximativement comprises ou pratiquées, de la découverte des touches de raccourci à la résolution des deux problèmes clés des touches de raccourci. Chaque solution présente des avantages et des inconvénients, tels qu'une incohérence commerciale, des difficultés de mise en œuvre, etc. Vous pouvez effectuer les ajustements et modifications correspondants en fonction des caractéristiques actuelles de votre propre entreprise et de l'infrastructure actuelle de l'entreprise.
Pour plus de connaissances sur la programmation, veuillez visiter :
Introduction à la programmation ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!