>  기사  >  데이터 베이스  >  Redis 최적화 사례 분석

Redis 최적화 사례 분석

WBOY
WBOY앞으로
2023-06-01 08:38:05650검색

메모리 차원

키 길이 제어

키는 일반적으로 문자열을 사용하며 문자열의 기본 데이터 구조는 SDS입니다. SDS 구조에는 문자열 길이, 할당된 공간 크기 등과 같은 메타데이터 정보가 포함됩니다. 문자열의 길이가 길어지면 SDS의 메타데이터도 더 많은 메모리 공간을 차지하게 됩니다. 키가 차지하는 공간을 줄이기 위해 업체 이름에 따라 해당하는 영어 약어를 사용하여 표현할 수 있습니다. 예를 들어 사용자는 u로 표시되고 메시지는 m으로 표시됩니다.

bigkey 저장을 피하세요

키의 길이와 값의 크기에 모두 주의해야 합니다. Redis는 단일 스레드를 사용하여 데이터를 읽고 씁니다. bigkey의 읽기 및 쓰기 작업은 스레드를 차단하고 크기를 줄입니다. Redis의 처리 효율성.

bigkey를 쿼리하는 방법

--bigkey 명령을 사용하면 Redis에서 차지하는 bigkey 정보를 볼 수 있습니다. 구체적인 명령은 다음과 같습니다.

redis-cli -h 127.0.0.1 -p 6379 -a 'xxx' --bigkeys

Redis 최적화 사례 분석

위 그림과 같이 볼 수 있습니다. Redis의 키는 32098바이트를 차지하므로 최적화가 필요합니다.

권장사항:

  • 키가 문자열 유형인 경우 값에 저장되는 값의 크기는 10KB 정도를 권장합니다.

  • 키가 List/Hash/Set/ZSet 유형인 경우 저장되는 요소 수를 10,000개 이하로 제어하는 ​​것이 좋습니다.

적절한 데이터 유형을 선택하세요

Redis는 저장된 데이터 유형에 최적화되어 있으며 그에 따라 메모리도 최적화되어 있습니다. 데이터 결과에 대한 관련 지식은 이전 기사를 참조할 수 있습니다.

예: String 및 set은 int 데이터를 저장할 때 정수 인코딩을 사용합니다. Hash와 ZSet은 요소 수가 상대적으로 적을 때 압축된 목록(ziplist) 저장소를 사용하고, 상대적으로 많은 양의 데이터가 저장될 때 해시 테이블 및 점프 테이블로 변환됩니다.

효율적인 직렬화 및 압축 방법 채택

Redis의 문자열은 바이너리 안전 바이트 배열을 사용하여 저장되므로 비즈니스를 바이너리로 직렬화하여 Redis에 쓸 수 있지만 차지하는 공간은 다릅니다. Protostuff의 직렬화는 Java의 내장 직렬화보다 더 효율적이며 공간을 덜 차지합니다. 공간 사용량을 줄이기 위해 JSON 및 XML 데이터 형식을 압축하고 저장할 수 있습니다. 선택적 압축 알고리즘에는 Gzip 및 Snappy가 포함됩니다.

Redis 최대 메모리 설정 및 제거 전략

Redis 메모리의 지속적인 확장과 너무 많은 리소스 점유를 방지하기 위해 비즈니스 데이터의 양을 기반으로 메모리 크기를 미리 예측합니다.

제거 전략을 설정하는 방법과 관련하여 실제 비즈니스 특성을 결합하여 선택해야 합니다.

  • 휘발성-lru / allkeys-lru: 최근에 액세스한 데이터를 유지하는 데 우선 순위를 지정합니다.

  • 휘발성- lfu / allkeys -lfu: 가장 자주 액세스하는 데이터 보관 우선순위 지정

  • 휘발성-ttl: 곧 만료되는 만료되는 데이터 우선순위 지정

  • 휘발성-random/allkeys-random: 데이터를 무작위로 제거

Redis 인스턴스 크기 제어

Redis 단일 인스턴스의 메모리 크기는 2~6GB 사이로 설정하는 것이 좋습니다. RDB 스냅샷 및 마스터-슬레이브 클러스터 데이터 동기화가 신속하게 완료될 수 있으므로 정상적인 요청 처리가 차단되지 않습니다.

메모리 조각을 정기적으로 삭제하세요

자주 새로운 수정으로 인해 메모리 조각이 증가하므로 메모리 조각을 제때에 삭제해야 합니다.

Redis는 다음과 같이 메모리 사용량 정보를 볼 수 있는 Info 메모리 명령을 제공합니다.

Redis 최적화 사례 분석

설명:

  • used_memory_rss는 운영 체제에서 실제로 Redis에 할당한 물리적 메모리 공간입니다.

  • used_memory는 Redis가 데이터를 저장하기 위해 실제로 적용한 공간입니다.

  • mem_fragmentation_ratio=used_memory_rss/used_memory

  • mem_fragmentation_ratio는 1보다 크고 1.5보다 작습니다. 이 상황은 합리적입니다.

  • mem_fragmentation_ratio가 1.5보다 크면 메모리 조각화 비율이 50% 이상에 도달했다는 의미입니다. 이 경우 일반적으로 메모리 조각화 속도를 줄이기 위해 몇 가지 조치를 취해야 합니다. 구체적인 메모리 정리 방법은 후속 기사에서 설명됩니다.

성능 차원

KEYS, FLUSHALL 및 FLUSHDB 명령을 사용할 수 없습니다.

  • KEYS는 키 내용에 따라 일치하고 일치 조건을 충족하는 키-값 쌍을 반환합니다. 이 명령에는 전체 테이블 스캔이 필요합니다. Redis 글로벌 해시 테이블이 Redis 메인 스레드를 심각하게 차단하고 있습니다.

  • FLUSHALL은 Redis 인스턴스의 모든 데이터를 삭제합니다. 데이터 양이 많으면 Redis 메인 스레드가 심각하게 차단됩니다.

  • FLUSHDB는 현재 데이터베이스의 데이터를 삭제합니다. 데이터 양이 많으면 Redis 메인 스레드가 차단됩니다.

최적화 제안

온라인에서 이 명령을 비활성화해야 합니다. 구체적인 방법은 클라이언트가 이러한 명령을 사용할 수 없도록 관리자가 rename-command 명령을 사용하여 구성 파일에서 이러한 명령의 이름을 바꾸는 것입니다.

慎用全量操作的命令

对于集合类型的来说,在未清楚集合数据大小的情况下,慎用查询集合中的全量数据,例如Hash的HetALL、Set的SMEMBERS命令、LRANGE key 0 -1 或者ZRANGE key 0 -1等命令,因为这些命令会对Hash或者Set类型的底层数据进行全量扫描,当集合数据量比较大时,会阻塞Redis的主线程。

优化建议:

当元素数据量较多时,可以用SSCAN、HSCAN 命令分批返回集合中的数据,减少对主线程的阻塞。

慎用复杂度过高命令

Redis执行复杂度过高的命令,会消耗更多的 CPU 资源,导致主线程中的其它请求只能等待。常见的复杂命令如下:SORT、SINTER、SINTERSTORE、ZUNIONSTORE、ZINTERSTORE 等聚合类命令。

优化建议:

当需要执行排序、交集、并集操作时,可以在客户端完成,避免让Redis进行过多计算,从而影响Redis性能。

设置合适的过期时间

Redis通常用于保存热数据。热数据一般都有使用的时效性。因此,在数据存储的过程中,应根据业务对数据的使用时间合理地设置数据的过期时间。否则写入Redis的数据会一直占用内存,如果数据持续增增长,会达到机器的内存上限,造成内存溢出,导致服务崩溃。

采用批量命令代替个命令

当我们需要一次性操作多个key时,可以使用批量命令来处理,批量命令可以减少客户端与服务端的来回网络IO次数。

  • String或者Hash类型可以使用 MGET/MSET替代 GET/SET,HMGET/HMSET替代HGET/HSET

  • 其它数据类型使用Pipeline命令,一次性打包发送多个命令到服务端执行。

Pipeline具体使用:
redisTemplate.executePipelined(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                for (int i = 0; i < 5; i++) 
                {
                    connection.set(("test:" + i).getBytes(), "test".getBytes());
                }
                return null;
            }
        });

高可用维度

按照业务部署不同的实例

不同的业务线来部署 Redis 实例,这样当其中一个实例发生故障时,不会影响到其它业务。

避免单点问题

业务上根据实际情况采用主从、哨兵、集群方案,避免单点故障,影响业务的正常使用。

合理的设置相关参数

针对主从环境,我们需要合理设置相关参数,具体内容如下:

  • 合理的设置repl-backlog参数:如果repl-backlog设置过小,当写流量比较大的场景下,主从复制中断可能会引发全量复制数据的风险。

  • 合理设置slave client-output-buffer-limit:当从库复制发生问题时,过小的 buffer会导致从库缓冲区溢出,从而导致复制中断。

위 내용은 Redis 최적화 사례 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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