Redis 사용 시 주의해야 할 21가지 사항(요약)

青灯夜游
풀어 주다: 2021-03-24 11:34:23
앞으로
2844명이 탐색했습니다.

이 글에서는 Redis를 사용할 때 꼭 알아야 할 21가지 사항을 공유하겠습니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

Redis 사용 시 주의해야 할 21가지 사항(요약)

1. Redis 사용 사양

1.1. 주요 사양 포인트

Redis 키를 설계할 때 다음 사항에 주의해야 합니다.

  • 업체 이름 키 접두사가 붙고 키 충돌 덮어쓰기를 방지하기 위해 콜론으로 구분됩니다. 예를 들어 live:rank:1
  • 키의 의미를 명확하게 하려면 키 길이가 30자 정도로 짧아야 합니다.
  • key에는 공백, 줄 바꿈, 작은따옴표 및 큰따옴표, 기타 이스케이프 문자와 같은 특수 문자를 포함할 수 없습니다.
  • Redis 키는 사용하지 않는 키가 제때에 지워지거나 제거될 수 있도록 최대한 ttl로 설정해야 합니다.

1.2. 값 명세 핵심 포인트

Redis의 값은 마음대로 정할 수 없습니다.

첫 번째 요점은 많은 수의 bigKey가 저장되면 문제가 발생하여 쿼리 속도가 느려지고 메모리가 과도하게 증가하는 등의 문제가 발생한다는 것입니다.

  • String 타입이라면 단일 값의 크기는 10k 이내로 조절되어야 합니다.
  • 해시, 리스트, 세트, ​​zset 유형인 경우 요소 수는 일반적으로 5000개를 초과하지 않습니다.

두 번째 포인트는 적절한 데이터 유형을 선택하는 것입니다. 많은 친구들은 주로 설정하고 가져오는 Redis의 문자열 유형만 사용합니다. 실제로 Redis는 풍부한 데이터 구조 유형을 제공합니다. 일부 비즈니스 시나리오에서는 hash 및 zset과 같은 다른 데이터 결과에 더 적합합니다. [관련 권장사항: Redis 동영상 튜토리얼]hash、zset等其他数据结果。【相关推荐:Redis视频教程

Redis 사용 시 주의해야 할 21가지 사항(요약)

反例:

set user:666:name jay
set user:666:age 18
로그인 후 복사

正例

hmset user:666 name jay age 18
로그인 후 복사

1.3. 给Key设置过期时间,同时注意不同业务的key,尽量过期时间分散一点

  • 因为Redis的数据是存在内存中的,而内存资源是很宝贵的。
  • 我们一般是把Redis当做缓存来用,而不是数据库,所以key的生命周期就不宜太长久啦。
  • 因此,你的key,一般建议用expire设置过期时间

如果大量的key在某个时间点集中过期,到过期的那个时间点,Redis可能会存在卡顿,甚至出现缓存雪崩现象,因此一般不同业务的key,过期时间应该分散一些。有时候,同业务的,也可以在时间上加一个随机值,让过期时间分散一些。

1.4.建议使用批量操作提高效率

我们日常写SQL的时候,都知道,批量操作效率会更高,一次更新50条,比循环50次,每次更新一条效率更高。其实Redis操作命令也是这个道理。

Redis客户端执行一次命令可分为4个过程:1.发送命令-> 2.命令排队-> 3.命令执行-> 4. 返回结果。1和4 称为RRT(命令执行往返时间)。 Redis提供了批量操作命令,如mget、mset等,可有效节约RRT。但是呢,大部分的命令,是不支持批量操作的,比如hgetall,并没有mhgetall存在。Pipeline 则可以解决这个问题。

Pipeline是什么呢?它能将一组Redis命令进行组装,通过一次RTT传输给Redis,再将这组Redis命令的执行结果按顺序返回给客户端.

我们先来看下没有使用Pipeline执行了n条命令的模型:

Redis 사용 시 주의해야 할 21가지 사항(요약)

使用Pipeline执行了n次命令,整个过程需要1次RTT,模型如下:

Redis 사용 시 주의해야 할 21가지 사항(요약)

2、Redis 有坑的那些命令

2.1. 慎用<span style="font-size: 18px;">O(n)</span>复杂度命令,如<span style="font-size: 18px;">hgetall</span><span style="font-size: 18px;">smember</span><span style="font-size: 18px;">lrange</span>Redis 사용 시 주의해야 할 21가지 사항(요약)

카운터 예:

keys key前缀*
로그인 후 복사
로그인 후 복사
🎜🎜Positive example 🎜🎜
if(jedis.setnx(key_resource_id,lock_value) == 1){ //加锁
    expire(key_resource_id,100); //设置过期时间
    try {
        do something  //业务请求
    }catch(){
  }
  finally {
       jedis.del(key_resource_id); //释放锁
    }
}
로그인 후 복사
로그인 후 복사
🎜🎜🎜1.3 Key의 만료 시간을 설정하고, 각 업체의 키에 주의하여 만료 시간을 최대한 분산시키도록 노력하세요🎜🎜🎜🎜🎜Redis 데이터는 메모리에 저장되기 때문입니다. , 메모리 리소스는 매우 소중합니다. 🎜🎜우리는 일반적으로 Redis를 캐시로 사용하고 🎜는 데이터베이스가 아니므로🎜 키의 수명 주기가 너무 길어서는 안 됩니다. 🎜🎜따라서 일반적으로 🎜expire를 사용하여 키의 만료 시간🎜을 설정하는 것이 좋습니다. 🎜🎜🎜특정 시점에 많은 수의 키가 만료되면 Redis가 만료 시점에 정체되거나 심지어 🎜캐시 사태🎜까지 발생할 수 있으므로 일반적으로 여러 업체의 키 만료 시간을 분산시켜야 합니다. 때로는 같은 업종에 종사하는 경우 시간에 임의의 값을 추가하여 만료 시간을 분산시킬 수도 있습니다. 🎜🎜🎜🎜1.4 효율성을 높이려면 일괄 작업을 사용하는 것이 좋습니다🎜🎜🎜🎜우리는 매일 SQL을 작성할 때 한 번에 50개 항목을 업데이트하는 것이 50번 반복하는 것보다 더 효율적이라는 것을 알고 있습니다. 매번 하나의 항목을 업데이트합니다. 실제로 Redis 작업 명령에도 동일한 원칙이 적용됩니다. 🎜🎜Redis 클라이언트에서 명령을 실행하는 과정은 4가지 프로세스로 나눌 수 있습니다: 1. 명령 보내기 -> 2. 명령 대기열 -> 3. 명령 실행 -> 4. 결과 반환. 1과 4를 RRT(명령 실행 왕복 시간)라고 합니다. Redis는 RRT를 효과적으로 절약할 수 있는 mget, mset🎜 등과 같은 🎜배치 작업 명령을 제공합니다. 그러나 대부분의 명령은 hgetall과 같은 일괄 작업을 지원하지 않으며 mhgetall은 존재하지 않습니다. 🎜Pipeline🎜이 이 문제를 해결할 수 있습니다. 🎜🎜파이프라인이란 무엇인가요? Redis 명령 집합을 모아 RTT를 통해 Redis로 전송한 다음 이 Redis 명령 집합의 실행 결과를 순서대로 클라이언트에 반환할 수 있습니다.🎜🎜먼저 파이프라인을 사용하지 않는 방법을 살펴보겠습니다. n 명령을 실행한 모델: 🎜🎜2 .png 🎜🎜 파이프라인을 사용하여 n개의 명령을 실행합니다. 전체 프로세스에는 1 RTT가 필요합니다. 모델은 다음과 같습니다: 🎜🎜Redis 사용 시 주의해야 할 21가지 사항(요약) 🎜🎜🎜🎜2. Redis🎜🎜🎜🎜🎜🎜2.1에 함정이있는 명령.주의 🎜O (n)🎜🎜복잡성 명령(예: 🎜🎜hgetall🎜🎜, 🎜🎜smember🎜🎜, 🎜🎜lrange🎜🎜Wait🎜🎜🎜🎜Redis는 단일 스레드에서 명령을 실행하기 때문입니다. hgetall 및 smember와 같은 명령의 시간 복잡도는 O(n)입니다. n이 계속 증가하면 Redis CPU가 계속해서 급증하여 다른 명령의 실행을 차단하게 됩니다. 🎜<blockquote>hgetall、smember,lrange等这些命令不是一定不能使用,需要综合评估数据量,明确n的值,再去决定。 比如hgetall,如果哈希元素n比较多的话,可以优先考虑使用<strong>hscan</strong>。</blockquote> <p><strong><span style="font-size: 18px;">2.2 慎用Redis的monitor命令</span></strong></p> <p>Redis Monitor 命令用于实时打印出Redis服务器接收到的命令,如果我们想知道客户端对redis服务端做了哪些命令操作,就可以用Monitor 命令查看,但是它一般<strong>调试</strong>用而已,尽量不要在生产上用!因为<strong>monitor命令可能导致redis的内存持续飙升。</strong></p> <blockquote>monitor的模型是酱紫的,它会将所有在Redis服务器执行的命令进行输出,一般来讲Redis服务器的QPS是很高的,也就是如果执行了monitor命令,Redis服务器在Monitor这个客户端的输出缓冲区又会有大量“存货”,也就占用了大量Redis内存。</blockquote> <p><img src="https://img.php.cn/upload/image/778/919/256/161655616710083Redis%20%EC%82%AC%EC%9A%A9%20%EC%8B%9C%20%EC%A3%BC%EC%9D%98%ED%95%B4%EC%95%BC%20%ED%95%A0%2021%EA%B0%80%EC%A7%80%20%EC%82%AC%ED%95%AD(%EC%9A%94%EC%95%BD)" title="161655616710083Redis 사용 시 주의해야 할 21가지 사항(요약)" alt="Redis 사용 시 주의해야 할 21가지 사항(요약)"></p> <p><strong><span style="font-size: 18px;">2.3、生产环境不能使用 keys指令</span></strong></p> <p>Redis Keys 命令用于查找所有符合给定模式pattern的key。如果想查看Redis 某类型的key有多少个,不少小伙伴想到用keys命令,如下:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">keys key前缀*</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div> <p>但是,redis的<code>keys是遍历匹配的,复杂度是O(n),数据库数据越多就越慢。我们知道,redis是单线程的,如果数据比较多的话,keys指令就会导致redis线程阻塞,线上服务也会停顿了,直到指令执行完,服务才会恢复。因此,一般在生产环境,不要使用keys指令。官方文档也有声明:

Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don't use KEYS in your regular application code. If you're looking for a way to find keys in a subset of your keyspace, consider using sets.

其实,可以使用scan指令,它同keys命令一样提供模式匹配功能。它的复杂度也是 O(n),但是它通过游标分步进行,不会阻塞redis线程;但是会有一定的重复概率,需要在客户端做一次去重

scan支持增量式迭代命令,增量式迭代命令也是有缺点的:举个例子, 使用 SMEMBERS 命令可以返回集合键当前包含的所有元素, 但是对于 SCAN 这类增量式迭代命令来说, 因为在对键进行增量式迭代的过程中, 键可能会被修改, 所以增量式迭代命令只能对被返回的元素提供有限的保证 。

2.4 禁止使用flushall、flushdb

  • Flushall 命令用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。
  • Flushdb 命令用于清空当前数据库中的所有 key。

这两命令是原子性的,不会终止执行。一旦开始执行,不会执行失败的。

2.5 注意使用del命令

删除key你一般使用什么命令?是直接del?如果删除一个key,直接使用del命令当然没问题。但是,你想过del的时间复杂度是多少嘛?我们分情况探讨一下:

  • 如果删除一个String类型的key,时间复杂度就是O(1)可以直接del
  • 如果删除一个List/Hash/Set/ZSet类型时,它的复杂度是O(n), n表示元素个数。

因此,如果你删除一个List/Hash/Set/ZSet类型的key时,元素越多,就越慢。当n很大时,要尤其注意,会阻塞主线程的。那么,如果不用del,我们应该怎么删除呢?

  • 如果是List类型,你可以执行lpop或者rpop,直到所有元素删除完成。
  • 如果是Hash/Set/ZSet类型,你可以先执行hscan/sscan/scan查询,再执行hdel/srem/zrem依次删除每个元素。

2.6 避免使用SORT、SINTER等复杂度过高的命令。

执行复杂度较高的命令,会消耗更多的 CPU 资源,会阻塞主线程。所以你要避免执行如SORT、SINTER、SINTERSTORE、ZUNIONSTORE、ZINTERSTORE等聚合命令,一般建议把它放到客户端来执行。

3、项目实战避坑操作

3.1 分布式锁使用的注意点

分布式锁其实就是,控制分布式系统不同进程共同访问共享资源的一种锁的实现。秒杀下单、抢红包等等业务场景,都需要用到分布式锁。我们经常使用Redis作为分布式锁,主要有这些注意点:

3.1.1 两个命令SETNX + EXPIRE分开写(典型错误实现范例)

if(jedis.setnx(key_resource_id,lock_value) == 1){ //加锁
    expire(key_resource_id,100); //设置过期时间
    try {
        do something  //业务请求
    }catch(){
  }
  finally {
       jedis.del(key_resource_id); //释放锁
    }
}
로그인 후 복사
로그인 후 복사

如果执行完setnx加锁,正要执行expire设置过期时间时,进程crash或者要重启维护了,那么这个锁就“长生不老”了,别的线程永远获取不到锁啦,所以一般分布式锁不能这么实现。

3.1.2 SETNX + value值是过期时间 (有些小伙伴是这么实现,有坑)

long expires = System.currentTimeMillis() + expireTime; //系统时间+设置的过期时间
String expiresStr = String.valueOf(expires);

// 如果当前锁不存在,返回加锁成功
if (jedis.setnx(key_resource_id, expiresStr) == 1) {
        return true;
} 
// 如果锁已经存在,获取锁的过期时间
String currentValueStr = jedis.get(key_resource_id);

// 如果获取到的过期时间,小于系统当前时间,表示已经过期
if (currentValueStr != null && Long.parseLong(currentValueStr) <p>这种方案的<strong>缺点</strong>:</p><blockquote><ul>
<li>过期时间是客户端自己生成的,分布式环境下,每个客户端的时间必须同步</li>
<li>没有保存持有者的唯一标识,可能被别的客户端释放/解锁。</li>
<li>锁过期的时候,并发多个客户端同时请求过来,都执行了<code>jedis.getSet()</code>,最终只能有一个客户端加锁成功,但是该客户端锁的过期时间,可能被别的客户端覆盖。</li>
</ul></blockquote><p><strong>3.1.3: SET的扩展命令(SET EX PX NX)(注意可能存在的问题)</strong></p><pre class="brush:php;toolbar:false">if(jedis.set(key_resource_id, lock_value, "NX", "EX", 100s) == 1){ //加锁
    try {
        do something  //业务处理
    }catch(){
  }
  finally {
       jedis.del(key_resource_id); //释放锁
    }
}
로그인 후 복사

这个方案还是可能存在问题:

  • 锁过期释放了,业务还没执行完。
  • 锁被别的线程误删。

3.1.4 SET EX PX NX + 校验唯一随机值,再删除(解决了误删问题,还是存在锁过期,业务没执行完的问题)

if(jedis.set(key_resource_id, uni_request_id, "NX", "EX", 100s) == 1){ //加锁
    try {
        do something  //业务处理
    }catch(){
  }
  finally {
       //判断是不是当前线程加的锁,是才释放
       if (uni_request_id.equals(jedis.get(key_resource_id))) {
        jedis.del(lockKey); //释放锁
        }
    }
}
로그인 후 복사

在这里,判断是不是当前线程加的锁和释放锁不是一个原子操作。如果调用jedis.del()释放锁的时候,可能这把锁已经不属于当前客户端,会解除他人加的锁。

Redis 사용 시 주의해야 할 21가지 사항(요약)

一般也是用lua脚本代替。lua脚本如下:

if redis.call('get',KEYS[1]) == ARGV[1] then 
   return redis.call('del',KEYS[1]) 
else
   return 0
end;
로그인 후 복사

3.1.5 Redisson框架 + Redlock算法 解决锁过期释放,业务没执行完问题+单机问题

Redisson 使用了一个Watch dog解决了锁过期释放,业务没执行完问题,Redisson原理图如下:

Redis 사용 시 주의해야 할 21가지 사항(요약)

以上的分布式锁,还存在单机问题: 

Redis 사용 시 주의해야 할 21가지 사항(요약)

如果线程一在Redis的master节点上拿到了锁,但是加锁的key还没同步到slave节点。恰好这时,master节点发生故障,一个slave节点就会升级为master节点。线程二就可以获取同个key的锁啦,但线程一也已经拿到锁了,锁的安全性就没了。

针对单机问题,可以使用Redlock算法。有兴趣的朋友可以看下我这篇文章哈,七种方案!探讨Redis分布式锁的正确使用姿势

3.2 缓存一致性注意点

  • 如果是读请求,先读缓存,后读数据库
  • 如果写请求,先更新数据库,再写缓存
  • 每次更新数据后,需要清除缓存
  • 缓存一般都需要设置一定的过期失效
  • 一致性要求高的话,可以使用biglog+MQ保证。

有兴趣的朋友,可以看下我这篇文章哈:并发环境下,先操作数据库还是先操作缓存?

3.3 合理评估Redis容量,避免由于频繁set覆盖,导致之前设置的过期时间无效。

我们知道,Redis的所有数据结构类型,都是可以设置过期时间的。假设一个字符串,已经设置了过期时间,你再去重新设置它,就会导致之前的过期时间无效。

Redis 사용 시 주의해야 할 21가지 사항(요약)

Redis setKey源码如下:

void setKey(redisDb *db,robj *key,robj *val) {
    if(lookupKeyWrite(db,key)==NULL) {
       dbAdd(db,key,val);
    }else{
    dbOverwrite(db,key,val);
    }
    incrRefCount(val);
    removeExpire(db,key); //去掉过期时间
    signalModifiedKey(db,key);
}
로그인 후 복사

实际业务开发中,同时我们要合理评估Redis的容量,避免频繁set覆盖,导致设置了过期时间的key失效。新手小白容易犯这个错误。

3.4 缓存穿透问题

先来看一个常见的缓存使用方式:读请求来了,先查下缓存,缓存有值命中,就直接返回;缓存没命中,就去查数据库,然后把数据库的值更新到缓存,再返回。

Redis 사용 시 주의해야 할 21가지 사항(요약)

캐시 침투: 존재하지 않아야 하는 데이터를 쿼리하는 것을 의미합니다. 캐시에 도달하지 않기 때문에 데이터를 찾을 수 없으면 캐시에 기록되지 않습니다. 존재하지 않는 데이터를 매번 요청하게 되어 데이터베이스에 압력을 가하게 됩니다.

간단히 말하면, 읽기 요청에 접근할 때 캐시나 데이터베이스 모두 특정 값을 갖고 있지 않으며, 이로 인해 이 값에 대한 각 쿼리 요청이 데이터베이스에 침투하게 됩니다.

캐시 침투는 일반적으로 다음과 같은 상황으로 인해 발생합니다.

  • 비합리적인 비즈니스 설계 예를 들어 대부분의 사용자는 가드를 활성화하지 않았지만 각 요청은 캐시되어 특정 사용자 ID 쿼리가 있습니다. 어떤 보호?
  • 캐시 및 데이터베이스 데이터가 실수로 삭제되는 등의 업무/운영 및 유지/개발 오류.
  • 해커에 의한 불법 요청 공격 예를 들어, 해커는 존재하지 않는 비즈니스 데이터를 읽기 위해 의도적으로 수많은 불법 요청을 조작합니다.

캐시 침투를 피하는 방법은 무엇입니까? 일반적으로 세 가지 방법이 있습니다.

  • 불법요청인 경우 API입구에서 매개변수를 확인하여 불법값을 걸러냅니다.
  • 쿼리 데이터베이스가 비어 있으면 캐시에 null 값이나 기본값을 설정할 수 있습니다. 그러나 쓰기 요청이 들어오면 캐시 일관성을 보장하기 위해 캐시를 업데이트해야 하며 동시에 캐시에 대한 적절한 만료 시간이 설정됩니다. (비즈니스에서 자주 사용되며 간단하고 효과적입니다.)
  • 블룸 필터를 사용하면 데이터 존재 여부를 빠르게 확인할 수 있습니다. 즉, 쿼리 요청이 들어오면 Bloom 필터를 통해 해당 값이 존재하는지 먼저 판단한 후 계속해서 존재하는지 확인하는 것입니다.
Bloom 필터 원리: 초기 값이 0인 비트맵 배열과 N개의 해시 함수로 구성됩니다. 키에 대해 N개의 해시 알고리즘을 수행하여 N개의 값을 비트 배열에서 해시하고 1로 설정합니다. 그런 다음 확인 시 이러한 특정 위치가 모두 1이면 블룸 필터링을 통해 서버는 키가 존재한다고 판단합니다. .

3.5 캐시 스노우런 문제

캐시 스노우런: 캐시에 있는 대용량 데이터의 만료 시간을 말하며 쿼리 데이터가 방대하고 요청이 데이터베이스에 직접 액세스하여 과도한 부담을 유발함 데이터베이스에 영향을 미치고 가동 중지 시간까지 발생합니다.

  • 캐시 폭설은 일반적으로 동시에 많은 양의 데이터가 만료될 때 발생합니다. 따라서 만료 시간을 균등하게 설정하는 것, 즉 만료 시간을 상대적으로 이산적으로 설정하면 해결할 수 있습니다. 더 큰 고정 값 + 더 작은 임의 값을 사용하는 경우 5시간 + 0 ~ 1800초입니다.
  • Redis 오류로 인해 캐시 폭설이 발생할 수도 있습니다. 이를 위해서는 Redis 고가용성 클러스터를 구축해야 합니다.

3.6 캐시 고장 문제

캐시 고장: 특정 시점에 핫스팟 키가 만료되는 경우를 말하며, 이 시점에서 이 키에 대한 동시 요청이 많이 발생하는 경우를 말하며, 따라서 많은 수의 요청이 db에 도달합니다.

캐시 분해는 약간 비슷해 보이지만 실제로는 캐시 충돌이 발생하면 데이터베이스가 과도한 압력을 받거나 심지어는 다운된다는 의미가 됩니다. 고장은 캐시 스노우런의 하위 집합이라고 간주할 수 있습니다. 일부 기사에서는 둘 사이의 차이점이 분석이 특정 단축키 캐시를 목표로 하는 반면 Xuebeng은 많은 키를 목표로 한다는 점이라고 생각합니다.

두 가지 해결책이 있습니다:

  • 1 뮤텍스 잠금 방식을 사용하세요. 캐시가 실패하면 db 데이터를 즉시 로드하는 대신 먼저 (Redis의 setnx)와 같은 성공적인 반환과 함께 일부 원자성 작업 명령을 사용하여 작업합니다. 성공하면 db 데이터베이스 데이터를 로드하고 캐시를 설정합니다. 그렇지 않으면 캐시를 다시 가져오십시오.
  • 2. "만료되지 않음"은 만료 시간이 설정되지 않았지만 핫스팟 데이터가 만료되려고 할 때 비동기 스레드가 업데이트되고 만료 시간을 설정한다는 의미입니다.

3.7.캐시 단축키 문제

Redis에서는 접근 빈도가 높은 키를 단축키라고 부릅니다. 특정 핫스팟 키에 대한 요청이 서버 호스트로 전송되는 경우 요청량이 특히 많아 호스트 리소스가 부족하거나 다운타임이 발생하여 정상적인 서비스에 영향을 줄 수 있습니다.

핫스팟 키는 어떻게 생성되나요? 두 가지 주요 이유가 있습니다:

  • 플래시 세일, 핫 뉴스 및 읽기가 많고 쓰기가 적은 기타 시나리오와 같이 사용자가 소비하는 데이터는 생성된 데이터보다 훨씬 큽니다.
  • 요청 샤딩이 집중되어 단일 Redi 서버의 성능을 초과합니다. 예를 들어 고정 이름 키와 해시가 동일한 서버에 속하고 즉각적인 액세스 양이 많아 시스템 병목 현상을 초과하고 핫키 문제가 발생합니다.

그렇다면 일상적인 개발에서 단축키를 식별하는 방법은 무엇일까요?

  • 경험을 바탕으로 어떤 단축키를 결정합니다.
  • 클라이언트 통계 보고
  • 서비스 에이전트 계층에 보고

단축키 문제를 해결하는 방법은 무엇입니까?

  • Redis 클러스터 확장: 읽기 트래픽의 균형을 맞추기 위해 샤드 복사본을 추가합니다.
  • 해시 단축키(예: key1, key2...keyN으로 키 백업, 동일한 데이터의 N 백업 및 다른 액세스 시 N 백업 배포) N개의 백업 중 하나에 무작위로 액세스하여 읽기 트래픽을 추가로 공유할 수 있습니다.
  • 두 번째 수준 캐시, 즉 JVM 로컬 캐시를 사용하여 Redis 읽기 요청을 줄이세요.

4. Redis 구성 및 운영

4.1 짧은 연결 대신 긴 연결을 사용하고 클라이언트의 연결 풀을 적절하게 구성하세요

  • 짧은 연결을 사용하는 경우 매번 TCP 3번의 핸드셰이크와 4번의 웨이브를 수행하면 필요한 시간이 늘어납니다. 그러나 장기간 연결의 경우 연결을 한 번 설정하면 redis 명령을 영원히 사용할 수 있으므로 redis 연결 설정 시간을 줄일 수 있습니다.
  • 연결 풀은 연결을 해제하지 않고도 클라이언트에서 여러 연결을 설정할 수 있으므로 매번 연결을 만들 필요가 없으므로 시간이 절약됩니다. 하지만 Redis가 오랫동안 작동되지 않을 경우에는 적절한 매개변수 설정이 필요합니다.

4.2는 db0

Redis 독립형 아키텍처에서 db0 이외의 사용을 금지합니다.

  • 연결에 대한 두 가지 이유가 있습니다. Redis는 select 0 및 select 1 명령을 실행하여 전환합니다. 새로운 에너지.
  • Redis 클러스터는 db0만 지원하며 마이그레이션 비용이 매우 많이 듭니다.

4.3 최대 메모리 설정 + 적절한 제거 전략.

메모리 백로그가 늘어나는 것을 방지하기 위해. 예를 들어, 비즈니스 볼륨이 증가할 때 Redis 키를 많이 사용하고 메모리가 부족하여 운영 및 유지 관리 담당자가 메모리를 늘리는 것을 잊어버리는 경우가 있습니다. Redis가 이렇게 끊을 수 있을까요? 따라서 maxmemory-policy(최대 메모리 제거 정책)를 선택하고 실제 업무에 맞춰 만료 시간을 설정해야 합니다. 총 8가지 메모리 제거 전략이 있습니다.

  • 휘발성-lru: 메모리가 새로 작성된 데이터를 수용하기에 충분하지 않은 경우 LRU(최근 사용) 알고리즘을 사용하여 만료 시간이 설정된 키를 제거합니다. allkeys-lru : 새로 작성된 데이터를 수용할 만큼 메모리가 충분하지 않은 경우 LRU(최근 사용) 알고리즘을 사용하여 모든 키를 제거합니다.
  • 휘발성-lfu: 버전 4.0에 새로 추가되었으며, 새로 작성된 데이터를 수용할 만큼 메모리가 충분하지 않은 경우 LFU 알고리즘을 사용하여 만료된 키 중에서 키를 삭제합니다.
  • allkeys-lfu: 버전 4.0의 새로운 기능으로 새로 작성된 데이터를 수용할 만큼 메모리가 충분하지 않은 경우 LFU 알고리즘을 사용하여 모든 키에서 제거합니다. 새로 작성된 데이터는 만료 시간이 설정된 키에서 데이터가 무작위로 제거됩니다.
  • allkeys-random: 메모리가 새로 작성된 데이터를 수용하기에 충분하지 않으면 모든 키에서 데이터가 무작위로 제거됩니다.
  • 휘발성-ttl: 새로 작성된 데이터를 수용할 만큼 메모리가 충분하지 않은 경우 만료 시간이 설정된 키가 만료 시간에 따라 제거되고, 이전에 만료된 키가 먼저 제거됩니다.
  • noeviction: The 기본 전략은 메모리가 부족한 경우 새로 작성된 데이터를 수용하기 위해 새 쓰기 작업에서 오류를 보고합니다.
  • 4.4 지연 방지 메커니즘 켜기

Redis4.0+ 버전이 지연 방지 메커니즘을 지원하는 Redis가 여전히 bigKey와 같은 기능을 지원한다면 지연 방지 기능을 켜는 것이 좋습니다. 켜져 있을 때 Redis가 빅키를 삭제하면 시간이 많이 소요되는 메모리 해제 작업이 백그라운드 스레드에서 실행되어 메인 스레드에 대한 차단 영향을 줄입니다.

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

프로그래밍 비디오Redis 사용 시 주의해야 할 21가지 사항(요약)를 방문하세요! !

위 내용은 Redis 사용 시 주의해야 할 21가지 사항(요약)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:segmentfault.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿