부적절한 명령을 사용하면 클라이언트가 차단됩니다.
keys *: 모든 키 작업을 가져옵니다.
Hgetall: 해시 테이블의 모든 필드 합계를 반환합니다.
smembers: 모든 구성원을 반환합니다.
이러한 명령의 시간 복잡도는 O(n)이며 때로는 전체 테이블을 스캔하므로 n이 증가하면 시간 소모가 늘어나 클라이언트가 차단됩니다.
Redis가 RDB 스냅샷을 찍을 때 시스템 함수 fork()를 호출하여 임시 파일 쓰기를 완료하는 하위 스레드를 생성하고 트리거 조건이 구성 파일의 저장 구성이라는 것을 누구나 알고 있습니다. .
구성에 도달하면 bgsave 명령이 실행되어 스냅샷을 생성합니다. 이 방법은 메인 스레드를 차단하지 않지만 save 명령을 수동으로 실행하면 메인 스레드에서 실행되어 메인 스레드를 차단합니다.
동기 지속성Redis가 AOF 로그를 직접 기록할 때 쓰기 작업이 많고 동기 지속성으로 구성된 경우appendfsync always
BGREWRITEAOF
명령을 실행할 때 Redis 서버는 하위 스레드에 저장될 AOF 다시 쓰기 버퍼를 유지합니다. 스레드가 새 AOF 파일을 생성하는 동안 서버에서 실행된 모든 쓰기 명령이 기록됩니다. BGREWRITEAOF
命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子线程创建新 AOF 文件期间,记录服务器执行的所有写命令。
当子线程完成创建新 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新的 AOF 文件保存的数据库状态与现有的数据库状态一致。
最后,服务器用新的 AOF 文件替换旧的 AOF 文件,以此来完成 AOF 文件重写操作。
阻塞就是出现在第2步的过程中,将缓冲区中新数据写到新文件的过程中会产生阻塞。
AOF 的日志记录不像关系型数据库那样在执行命令之前记录日志(方便故障恢复),而是采用先执行命令后记录日志的方式。
原因就是 AOF 记录日志是不会对命令进行语法检查的,这样就能减少额外的检查开销,不会对当前命令的执行产生阻塞,但可能会给下一个操作带来阻塞风险。
这是因为 AOF 日志也是在主线程中执行的,如果在把日志文件写入磁盘时,磁盘写压力大,就会导致写盘很慢,进而导致后续的操作也无法执行了。
大 key 并不是指 key 的值很大,而是 key 对应的 value 很大。
大 key 造成的阻塞问题如下:
客户端超时阻塞:由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时,那么就会阻塞 Redis,从客户端这一视角看,就是很久很久都没有响应。
引发网络阻塞:每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的。
阻塞工作线程:如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令。
当我们在使用 Redis 自带的 --bigkeys
하위 스레드가 새 AOF 파일 생성 작업을 완료하면 서버는 다시 쓰기 버퍼의 모든 내용을 새 AOF 파일 끝에 추가하므로 새 AOF 파일에 저장된 데이터베이스 상태는 다음과 같습니다. 기존 데이터베이스 상태와 일치합니다.
마지막으로 서버는 이전 AOF 파일을 새 AOF 파일로 대체하여 AOF 파일 다시 쓰기 작업을 완료합니다.
차단은 2단계에서 발생합니다. 버퍼에 있는 새 데이터를 새 파일에 쓰는 과정에서
차단큰 키는 키의 값이 매우 크다는 의미가 아니라 키에 해당하는 값이 매우 크다는 의미입니다.
큰 키로 인해 발생하는 차단 문제는 다음과 같습니다. 클라이언트 시간 초과 차단: Redis 실행 명령은 단일 스레드이므로 큰 키를 작동하는 데 더 많은 시간이 소요되며 이로 인해 Redis가 클라이언트에서 차단됩니다. 측면에서 보면, 오랫동안 아무런 반응이 없는 것 같습니다.
네트워크 정체 유발: 큰 키를 얻을 때마다 네트워크 트래픽이 커집니다. 키 크기가 1MB이고 초당 방문 횟수가 1000이면 초당 1000MB의 트래픽이 생성됩니다. . 일반 기가비트용입니다. 네트워크 카드는 서버에 치명적입니다.
작업 스레드 차단: del을 사용하여 큰 키를 삭제하면 작업자 스레드가 차단되어 후속 명령을 처리할 수 없게 됩니다. 🎜🎜🎜큰 키 찾기
🎜큰 키를 찾기 위해 Redis와 함께 제공되는--bigkeys
매개변수를 사용할 때 슬레이브 노드에서 명령을 실행하는 것이 가장 좋습니다. 마스터 노드에서 실행되면 마스터 노드가 🎜차단🎜됩니다. 🎜🎜🎜🎜SCAN 명령을 사용하여 큰 키를 찾을 수도 있습니다. 🎜🎜🎜🎜큰 키를 식별하려면 먼저 Redis가 RDB 지속성을 사용하는지 확인하고 해당 RDB 파일을 분석해야 합니다. 인터넷에는 기성 도구가 있습니다. 🎜🎜🎜🎜🎜redis-rdb-tools: Redis RDB 스냅샷 파일을 분석하기 위해 Python 언어로 작성된 도구🎜🎜🎜🎜이 도구는 rdb_bigkeys라고 하며 Go 언어로 작성되었으며 더 높은 성능으로 Redis의 RDB 스냅샷 파일을 분석하는 데 사용할 수 있습니다. 🎜🎜🎜🎜🎜큰 키 삭제🎜🎜삭제 작업의 핵심은 키-값 쌍이 차지하는 메모리 공간을 해제하는 것입니다. 🎜🎜메모리 해제는 메모리 공간을 보다 효율적으로 관리하기 위한 첫 번째 단계일 뿐이며, 애플리케이션이 메모리를 해제할 때 🎜운영 체제는 후속 관리 및 재할당을 위해 해제된 메모리 블록을 사용 가능한 메모리 블록의 연결된 목록🎜에 삽입해야 합니다. . 이 프로세스 자체에는 시간이 걸리며 현재 메모리를 확보하고 있는 애플리케이션을 🎜차단🎜합니다. 🎜🎜그래서 한번에 많은 양의 메모리가 해제되면 여유 메모리 블록 연결 목록의 작동 시간이 늘어나므로 Redis 🎜메인 스레드가 차단됩니다🎜. 다른 요청도 시간 초과될 수 있으며, 이로 인해 Redis 연결이 소진되고 다양한 예외가 발생하게 됩니다. 🎜🎜🎜큰 키를 삭제할 때는 일괄 삭제와 비동기 삭제를 사용하는 것이 좋습니다. 🎜
데이터베이스 지우기는 위의 bigkey 삭제와 동일합니다. Flushdb 및 Flushall에는 Redis의 차단 지점이기도 한 모든 키-값 쌍을 삭제하고 해제하는 작업도 포함됩니다.
Redis 클러스터는 노드를 동적으로 확장 및 축소할 수 있습니다. 이 프로세스는 현재 반자동 상태이며 수동 개입이 필요합니다.
확장 및 축소 중에는 데이터 마이그레이션이 필요합니다. 마이그레이션의 일관성을 보장하기 위해 Redis의 모든 마이그레이션 작업은 동기식 작업입니다.
마이그레이션을 수행할 때 양쪽 끝의 Redis는 다양한 길이의 blocking 상태에 들어갑니다. 작은 키의 경우 이 시간은 무시할 수 있지만 키의 메모리 사용량이 너무 크면 심각한 경우 클러스터 내 장애 조치로 인해 불필요한 전환이 발생합니다.
위 내용은 Redis가 차단되는 상황은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!