>  기사  >  데이터 베이스  >  Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유

Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유

青灯夜游
青灯夜游앞으로
2022-02-10 18:45:583330검색

Redis의 단축키 문제를 어떻게 처리하나요? 다음 기사에서는 Redis 캐시 단축키 문제에 대한 일반적인 솔루션을 소개합니다. 도움이 되길 바랍니다.

Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유

일부 C 측 비즈니스를 수행할 때 데이터베이스의 부담을 대체하고 비즈니스 응답 시간을 줄이기 위해 1차 캐시를 도입하는 것은 불가피합니다. 실제로 문제를 해결하기 위해 매번 미들웨어가 도입됩니다. , 이는 이전 기사 "실제 데이터베이스 및 캐시 일관성"에서 언급한 캐시 일관성을 달성하는 방법과 같은 많은 새로운 문제를 필연적으로 야기할 것입니다. 실제로 Redis를 1차 캐시로 사용할 때 발생할 수 있는 핫키, 큰 키 등과 같은 다른 문제도 있을 것입니다. 이번 글에서는 핫키 및 <code>단축키 문제를 해결하는 방법. -

배경

热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访问。

Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유

Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유

        如上所说,热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에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유

        如下所示,可以看到redis-cli –hotkeys 단축키 어떻게 발생하나요?

🎜 일반적으로 우리가 사용하는 캐시 Redis는 다중 노드 클러스터 버전입니다. 특정 키를 읽고 쓸 때 해당 키의 해시를 기반으로 해당 슬롯을 계산하고 이를 기반으로 해당 슬롯을 찾을 수 있습니다. 슬롯. 샤딩(하나의 마스터와 여러 개의 슬레이브로 구성된 Redis 클러스터 집합)은 K-V에 액세스하는 데 사용됩니다. 그러나 실제 신청 과정에서 일부 특정 비즈니스 또는 특정 기간(예: 전자상거래 비즈니스의 제품 플래시 세일 활동)에서는 동일한 키에 대한 액세스 요청이 많이 발생할 수 있습니다. 모든 요청(그리고 그러한 요청의 읽기/쓰기 비율은 매우 높음)은 동일한 Redis 서버에 속하게 되며, 이때 Redis의 로드는 심각하게 증가하게 됩니다. 전체 시스템에 새로운 Redis 인스턴스를 추가하게 됩니다. 해시 알고리즘에 따르면 동일한 키에 대한 요청은 여전히 ​​동일한 새 시스템에 속하므로 시스템 병목 현상이 발생하고2 이 핫스팟 키의 값이 상대적으로 높을 경우 전체 클러스터가 충돌할 수도 있습니다. 크면 네트워크 카드에 병목 현상이 발생하게 됩니다. 이 문제를 "핫 키" 문제라고 합니다. [관련 권장 사항: Redis 동영상 튜토리얼]🎜🎜 그림 1과 2에 표시됨 아래는 각각 프록시 프록시 계층을 사용하는 일반적인 Redis 클러스터 클러스터 및 Redis 클러스터 키 액세스입니다. 🎜🎜Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유🎜🎜🎜🎜 위에서 언급했듯이, 핫키는 클러스터의 소수 노드에 매우 높은 로드 압력을 가져옵니다. 올바르게 처리하지 않으면 이러한 노드가 다운되어 전체 캐시 클러스터의 작동에 영향을 미칠 수 있으므로 제때에 핫키를 검색해야 합니다. 핫키 문제를 해결하세요. 🎜

1. 단축키 감지

🎜 단축키 감지, redis 클러스터와 단축키의 분산으로 인해 몇 가지 중요한 영향이 있음을 확인하고 대략적인 방법을 사용할 수 있습니다. 핫스팟 키 감지 솔루션을 개발하는 과정에 대해 알아보세요. 🎜

1.1 클러스터 내 각 슬롯의 QPS 모니터링

🎜 단축키의 가장 확실한 영향은 전체 Redis 클러스터의 QPS가 클러스터 내 슬롯들 사이에 트래픽이 고르게 분포되어 있다는 전제 하에, 먼저 각 슬롯의 트래픽을 모니터링하고, 각 슬롯의 트래픽을 비교한 후, 영향을 받은 특정 슬롯을 발견하면 단축키가 나타납니다. 이 모니터링은 가장 편리하지만 세분화가 너무 거칠기 때문에 초기 클러스터 모니터링 솔루션에만 적합하며 단축키가 정확하게 감지되는 시나리오에는 적합하지 않습니다. 🎜

1.2 프록시 메커니즘은 전체 트래픽 입구 통계로 사용됩니다.

🎜 그림 2에서 redis 클러스터 프록시 모드를 사용하는 경우, 모든 요청은 먼저 프록시로 이동한 다음 특정 슬롯 노드로 이동합니다. 그런 다음 이 단축키의 감지 통계는 시간 슬라이딩 창을 기반으로 프록시에서 수행될 수 있습니다. 각 키를 계산한 다음 해당 임계값을 초과하는 키를 계산합니다. 너무 많은 중복 통계를 방지하기 위해 접두사 및 유형에 해당하는 키만 계산하도록 일부 규칙을 설정할 수도 있습니다. 이 방법에는 최소한 프록시 메커니즘이 필요하며 Redis 아키텍처에 대한 요구 사항이 있습니다. 🎜

1.3 redis LFU 기반 핫스팟 키 검색 메커니즘

🎜 Redis 4.0 이상의 버전은 각 노드에서 LFU 기반 핫스팟을 지원합니다. 메커니즘을 사용하려면 redis-cli –hotkeys를 사용하세요. redis-cli를 실행할 때 –hotkeys 옵션을 추가하세요. 노드에서 정기적으로 이 명령을 사용하여 해당 핫스팟 키를 검색할 수 있습니다. 🎜🎜Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유🎜🎜 as 그림과 같이 redis-cli –hotkeys의 실행 결과와 단축키에 대한 통계 정보를 확인할 수 있으며, 이 명령의 실행 시간이 길며 예약 실행을 설정할 수 있습니다. 통계를 수집합니다. 🎜

1.4 Redis 클라이언트 기반 탐지

Redis 명령은 매번 클라이언트에서 발행되므로 이를 기반으로 Redis 클라이언트의 일부 코드에서 통계 계산을 수행할 수 있으며 각 클라이언트는 시간 슬라이딩 창을 기반으로 통계를 수행합니다. 특정 임계값을 초과하면 서버에 보고되고, 서버는 이를 각 클라이언트에 균일하게 전송하고 해당 만료 시간을 구성합니다.

이 방법은 더 아름다워 보이지만 실제로는 클라이언트 측 수정으로 인해 실행 중인 프로세스에 더 큰 메모리 오버헤드가 발생하기 때문에 일부 애플리케이션 시나리오에서는 그다지 적합하지 않습니다. 더 직접적으로는 다음과 같은 자동 메모리 관리 기능이 있는 언어입니다. Java와 goLang은 객체를 더 자주 생성하여 gc를 트리거하고 인터페이스 응답 시간을 증가시키는 것은 예측하기 쉽지 않습니다. 优美,其实在一些应用场景中并不是那么合适,因为在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的数量做取余。

Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유

2.4 本地缓存的另外一种思路 配置中心

        对于熟悉微服务配置中心的伙伴来讲,我们的思路可以向配置中心的一致性转变一下。拿nacos来举例,它是如何做到分布式的配置一致性的,并且相应速度很快?那我们可以将缓存类比配置,这样去做。

        长轮询+本地化

결국 각 기업의 인프라를 통해 그에 맞는 선택을 하게 됩니다. 🎜

2. 단축키 솔루션

🎜 위의 방법을 통해 해당 단축키 또는 핫슬롯을 감지한 다음 해당 단축키 문제를 해결해야 합니다. 단축키를 해결하는 방법에는 여러 가지가 있습니다. 하나씩 살펴보겠습니다. 🎜

🎜2.1 특정 키 또는 슬롯의 흐름을 제한합니다🎜🎜🎜 가장 간단하고 조잡한 방법은 특정 슬롯이나 단축키의 흐름을 제한하는 것입니다. 비즈니스 손실이 많기 때문에 온라인 문제가 있어 손실을 중지해야 하는 경우에만 특정 전류 제한을 사용하는 것이 좋습니다. 🎜

🎜2.2 2차(로컬) 캐시 사용 🎜🎜🎜 로컬 캐시는 가장 일반적으로 사용되는 솔루션이기도 합니다. 두 번째 수준 캐시를 추가합니다. 각 요청은 서비스에 의해 발행되므로 이 두 번째 수준 캐시를 서비스 측에 추가하는 것이 완벽합니다. 따라서 서버가 해당 핫키를 얻을 때마다 로컬 캐시를 사용하여 로컬 캐시까지 복사본을 저장할 수 있습니다. 그런 다음 Redis 클러스터에 대한 부담을 줄이기 위해 다시 요청하십시오. Java를 예로 들면 guavaCache는 이미 만들어진 도구입니다. 다음 예: 🎜rrreee🎜 로컬 캐시가 우리에게 미치는 가장 큰 영향은 데이터 불일치 문제입니다. 캐시 만료 시간을 얼마나 오래 설정하면 온라인 데이터 불일치 문제가 가장 길어질 수 있습니다. 이 캐시 시간은 자체 클러스터 압력을 측정해야 합니다. 비즈니스에서 허용하는 최대 불일치 시간. 🎜

🎜2.3 키 제거🎜🎜🎜 데이터 일관성을 최대한 보장하면서 단축키 문제가 발생하지 않도록 하려면 어떻게 해야 할까요? 키를 제거하는 것도 좋은 해결책입니다. 🎜🎜                                                                           캐시에 넣을 때 해당 비즈니스의 캐시 키를 여러 개의 다른 키로 분할합니다. 아래 그림과 같이 먼저 업데이트 캐시 측면에서 키를 N 부분으로 분할합니다. 예를 들어 키 이름이 "good_100"인 경우 "good_100_copy1", "good_100_copy2"의 네 부분으로 분할할 수 있습니다. ", " good_100_copy3", "good_100_copy4", 이 N 키는 업데이트되거나 추가될 때마다 변경해야 합니다. 이 단계는 키를 제거하는 것입니다. 🎜🎜 서비스 측면에서는 우리가 액세스하는 트래픽을 충분히 균일하게 만드는 방법과 우리가 액세스하려는 단축키에 접미사를 추가하는 방법을 찾아야 합니다. 머신의 IP 또는 MAC 주소를 기반으로 해시를 수행한 다음 나머지 값과 분할 키 수를 가져와 마지막으로 어떤 종류의 키 접미사를 접합할지 결정하는 방법에는 여러 가지가 있습니다. 서비스가 시작될 때 어느 시스템에 도달할지에 대한 것입니다. 임의의 숫자는 분할 키 수의 나머지입니다. 🎜🎜Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유🎜

🎜2.4 로컬 캐시 구성 센터에 대한 또 다른 생각🎜🎜🎜 마이크로서비스 구성 센터에 익숙한 사람들이라면 구성 센터의 일관성으로 생각이 바뀔 수 있습니다. nacos를 예로 들어보겠습니다. 분산 구성 일관성을 달성하고 신속하게 응답하는 방법은 무엇입니까? 그런 다음 캐시 비유를 구성과 비교하여 다음과 같이 수행할 수 있습니다. 🎜🎜 장기 폴링+현지화 구성. 먼저 서비스가 시작되면 모든 구성이 초기화된 후 정기적으로 롱 폴링이 시작되어 현재 서비스 모니터링 구성이 변경되었는지 확인합니다. 변경 사항이 있는 경우 롱 폴링 요청이 즉시 반환되어 로컬 구성을 업데이트합니다. 변경 사항이 없으면 모든 비즈니스 코드에 대해 로컬 메모리 캐시 구성을 사용합니다. 이는 분산 캐시 구성의 적시성과 일관성을 보장합니다. 🎜

2.5 사전에 수립할 수 있는 기타 계획

위의 각 솔루션은 단축키 문제를 해결하기 위해 상대적으로 독립적이므로 실제로 비즈니스 요구 사항에 직면하면 실제로 전체 솔루션 설계를 고려하는 데 오랜 시간이 걸립니다. . 일부 극단적인 플래시 판매 시나리오로 인해 발생하는 핫키 문제의 경우 예산이 충분하다면 서비스 비즈니스와 Redis 캐시 클러스터를 직접 격리하여 정상적인 비즈니스에 영향을 미치지 않도록 할 수 있으며 동시에 일시적으로 더 나은 재해 복구를 채택할 수 있습니다. 전류 제한 조치.

일부 통합 솔루션

시장에는 이미 상대적으로 완전한 핫키용 애플리케이션 수준 솔루션이 많이 있습니다. 그중 JD.com에는 이와 관련하여 클라이언트에 대한 통찰력을 제공하는 오픈 소스 핫키 도구가 있습니다. 측에서 응답 핫키를 보고하면 서버가 이를 감지한 후 로컬 캐싱을 위해 해당 핫키를 해당 서버로 보냅니다. 이 로컬 캐시는 원격 해당 키가 업데이트된 후 동시에 업데이트됩니다. 현재 솔루션, 自动探测热key、分布式一致性缓存JD Retail 단축키.

Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유

Summary

위 내용은 단축키 발견부터 단축키의 2가지 핵심 이슈 해결까지 저자가 대략적으로 이해하거나 실습한 단축키 처리 방법에 대한 몇 가지 해결 방법이다. 각 솔루션에는 비즈니스 불일치, 구현의 어려움 등 장단점이 있습니다. 귀하는 귀하의 비즈니스의 현재 특성과 현재 회사의 인프라를 기반으로 해당 조정 및 변경을 수행할 수 있습니다.

더 많은 프로그래밍 관련 지식을 보려면

프로그래밍 소개를 방문하세요! !

위 내용은 Redis에서 캐시 단축키 문제를 처리하는 방법에 대해 이야기해 볼까요? 일반적으로 사용되는 솔루션 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제