Redis 의 String 장르 가 일 으 킨 참사
그럼 메모리 소 모 를 줄 일 수 있 는 방법 이 있 습 니까?
String 형식의 데이터 구조
우선 String 이 데 이 터 를 저장 할 때 소모 하 는 메모리 공간 이 왜 큰 지 알 아야 합 니 다.방금 사례 에서 이미지 ID 와 이미지 저장 대상 ID 가 모두 10 자리 이기 때문에 우 리 는 8 바이트 의 Long 유형 두 개 로 이 두 ID 를 표시 할 수 있다.따라서 그림 ID 와 저장 대상 ID 의 기록 은 실제 16 바이트 만 있 으 면 된다.그러나 Redis 메모리 분석 을 통 해 이미지 ID 와 저장 대상 ID 가 64 바이트 를 차지 하 는데 왜 String 형식 은 64 바이트 를 사용 합 니까?사실 실제 데 이 터 를 기록 하 는 것 외 에 String 유형 은 데이터 의 길이,공간 사용 정보 등 을 기록 하 는 추가 메모리 공간 이 필요 하 다.이런 정 보 를 메타 데이터 라 고도 부른다.실제 저 장 된 데이터 가 시간 에 비해 메타 데이터 의 공간 비용 이 비교적 크다.String 형식 이 데 이 터 를 어떻게 저장 하 는 지 살 펴 보 겠 습 니 다.64 개의 기호 가 있 는 정 수 를 저장 할 때 String 형식 은 8 바이트 의 Long 형식 정수 로 저장 합 니 다.이런 저장 방식 은 보통 int 인 코딩 방식 이 라 고도 합 니 다.단,저 장 된 데이터 에 문 자 를 포함 할 때 String 형식 은 간단 한 동적 문자열 구조 체(SDS)로 저 장 됩 니 다.다음 그림 에서 보 듯 이:
메모리 공간 을 절약 하기 위해 Redis 는 Long 유형의 정수 와 SDS 의 메모리 레이아웃 을 전문 적 으로 설계 했다.한편,Long 형식의 정 수 를 저장 할 때 RedisObject 의 지침 은 정수 데이터 로 직접 할당 합 니 다.그러면 추가 지침 없 이 정 수 를 가리 키 고 지침 의 공간 비용 을 절약 할 수 있 습 니 다.다른 한편,문자열 데 이 터 를 저장 하고 문자열 이 44 바이트 보다 작 을 때 RedisObject 의 메타 데이터,포인터,SDS 는 연속 적 인 메모리 영역 으로 메모리 조각 을 피 할 수 있 습 니 다.이런 레이아웃 방식 도 embstr 인 코딩 방식 이 라 고 불 린 다.문자열 이 44 바이트 이상 이면 SDS 의 데이터 양 이 많아 지고 Redis 는 SDS 와
RedisObject 는 함께 배치 되 어 SDS 에 독립 된 공간 을 할당 하고 SDS 구 조 를 포인터 로 가리 키 게 됩 니 다.이런 레이아웃 방식 은 raw 인 코딩 모드 라 고 불 린 다.다음 그림 에서 보 듯 이:
이제 그림 ID 와 그림 저장 대상 ID 의 메모리 사용량 을 계산 해 봅 시다.10 자리 수의 이미지 ID 와 이미지 저장 대상 ID 는 Long 형식 정수 이기 때문에 int 인 코딩 의 RedisObject 로 직접 저장 할 수 있 습 니 다.이에 대응 하 는 RedisObject 메타 데이터 부분 은 8 바이트 이 고 포인터 부분 은 8 바이트 의 정수 로 직접 할당 되 었 습 니 다.이때 각 ID 는 16 바이트 로 합 쳐 모두 32 바이트 다.그런데 다른 32 바이트 가 어디 갔 지?
Redis 는 전역 해시 표를 사용 하여 모든 키 쌍 을 저장 하기 때문에 해시 표 의 모든 항목 은 dictEntity 의 구조 체 로 키 쌍 을 가리 키 고 있 습 니 다.dictEntity 는 세 개의 8 바이트 지침 으로 구성 되 어 있 으 며,각각 key,value 와 다음 dictEntity 를 가리킨다.아래 그림 과 같다.
Redis 가 사용 하 는 메모리 분배 라 이브 러 리 는 jemalloc 이기 때문에 jemalloc 는 메모 리 를 분배 할 때 신청 한 바이트 수 N 에 따라 N 보다 크 고 N 에 가장 가 까 운 2 의 멱 횟수 를 분배 하 는 공간 으로 찾 습 니 다.
그래서 24 바이트 의 dictEntity 를 신청 하면 실제 32 바이트 가 분 배 됩 니 다.
현재 위치 에 서 는 그림 ID 와 그림 저장 대상 ID 를 저장 하기 위해 String 형식 이 64 개의 바이트 를 차지 하 는 이 유 를 알 수 있 을 것 입 니 다.하나의 유효한 정 보 는 16 개의 바이트 에 불과 합 니 다.String 형식 으로 저장 할 때 64 개의 바이트 메모리 공간 을 차지 해 야 합 니 다.48 개의 바이트 가 메타 데이터 정 보 를 저장 하 는 데 사 용 됩 니 다.이것 은 메모리 공간 을 크게 낭비 하 는 것 이 아 닙 니까?그렇다면 메모리 절약 방법 은 없 을 까?
압축 목록 으로 메모리 절약
Redis 에는 압축 목록 이라는 구조 가 있어 메모 리 를 매우 절약 합 니 다.우 리 는 먼저 압축 목록 의 구성 을 되 돌아 보 았 다.표 머리 는 세 개의 필드 zlbytes,zllen 과 zltail 이 있 는데 각각 목록 의 길이,목록 끝의 오프셋 과 목록 중의 entry 의 개 수 를 나타 낸다.압축 목록 표 끝 에 zlend 가 있 습 니 다.목록 이 끝 났 음 을 표시 합 니 다.아래 그림 과 같다.
압축 목록 은 일련의 entry 로 데 이 터 를 저장 하기 때문에 이 entry 는 메모리 에 하나씩 놓 여 있 습 니 다.추가 포인터 로 연결 하지 않 아 도 됩 니 다.그러면 포인터 가 사용 하 는 공간 을 절약 할 수 있 습 니 다.각 entry 는 아래 의 몇 부분 으로 구성 되 어 있다.
Redis 에 서 는 압축 목록 을 기반 으로 List,Hash,Sorted Set 집합 형식 을 실 현 했 습 니 다.이렇게 하 는 가장 큰 장점 은 dictEntity 의 메모리 비용 을 절약 하 는 것 입 니 다.String 형식 에 있어 서 하나의 키 값 은 dictEntity 가 있 고 32 개의 바이트 가 있 습 니 다.집합 유형 에 있어 하나의 key 는 많은 데 이 터 를 대응 하지만 하나의 dictEntity 만 차지 하여 메모리 공간 을 절약 합 니 다.
어떻게 집합 형식 으로 단일 값 의 키 값 이 맞 는 데 이 터 를 저장 합 니까?
단일 키 값 이 맞 는 데 이 터 를 저장 할 때 Hash 형식 을 기반 으로 하 는 2 급 인 코딩 방식 을 사용 할 수 있 습 니 다.여기 서 말 하 는 2 급 인 코딩 은 단일 값 의 데 이 터 를 두 부분 으로 나 누고 앞부분 은 Hash 의 key 이 며 뒷부분 은 Hash 의 value 이다.그림 의 ID 는 1101021043 이 고 이에 대응 하 는 그림 저장 대상 의 ID 는 2301010051 입 니 다.저 희 는 그림 의 ID 앞 7 자리(1101021)를 Hash 형식의 키 로 하고,뒤 3 자리(043)와 그림 저장 대상 ID 는 2301010051 을 Hash 형식의 key 와 value 로 합 니 다.우 리 는 이러한 디자인 에 따라 Redis 에 하나의 기록 을 삽입 하고 16 바이트 만 차지 하기 때문에 String 형식 을 사용 하여 64 바이트 를 차지 하 는 것 과 비교 하여 많은 공간 을 절약 했다.마지막 으로,우 리 는 왜 그림 ID 의 앞 7 위 를 Hash 형식의 키 로 하고,뒤 3 위 를 Hash 형식의 키 로 해 야 하 는 지 다시 한 번 생각해 보 자.우 리 는Redis 메모리 구조에서 Redis 의 Hash 유형의 두 가지 바 텀 실현 구 조 를 소개 한 적 이 있 는데 그것 이 바로 압축 목록 과 해시 표 이다.Hash 형식 은 압축 목록 으로 데 이 터 를 저장 할 때의 두 개의 한도 값 을 설정 합 니 다.한도 값 을 초과 하면 Hash 형식 은 해시 표 로 데 이 터 를 저장 합 니 다.이 두 개의 한도 값 은 각각 다음 두 개의 설정 항목 에 대응 합 니 다.
레 디 스 의 한 스 트 링 장르 로 인 한 참사 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.레 디 스 트 링 장르 에 관 한 더 많은 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 읽 어 주시 기 바 랍 니 다.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
그래프 구조를 무상으로 취급할 수 없는 것은 싫기 때문에, redisgraph를 WSL2에 극치고 설치해 보았습니다.제목은 만우절이므로. 그렇다, 역시, 앞으로는 그래프 구조 데이터베이스라고 생각했다. 생각한 것은 몇 년 전인가. 전부터 Neo4j는 시험하고 있지만, 영업 분들로부터 상용 라이센스가 높다고 가르쳐 주었으므로, 전전...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.