(이전 + 공유) Redis 문자열은 어떻게 구현됩니까? / Xiao Xiaomu의 블로그 JAVA Xiaoka 어제 전날 쇼

출처 : www.cnblogs.com/wyc1994666/p/10669212.html

 

이전에 면접을 찾고 있었을 때 Redis 관련 문제에 갇혀있었습니다.

인터뷰 전에 저는 Redis의 5 가지 데이터 구조, Redis 지속성 전략, 분산 잠금의 Redis 구현, 간단한 게시 및 구독 등과 같은 일반적인 루틴에 따라 준비했습니다. 결국 Redis에서 묻는 질문 ~~

 

Interviewer :  일반적으로 사용되는 데이터 구조에 익숙한 이력서를보세요. 무엇에 대해 이야기할까요?
I :  일반적으로 사용되는 5 가지, 문자열, 목록, 집합, zset 및 해시 (매우 만족)

Interviewer :  그런 다음 어떤 데이터 구조를 사용했는지 알려주세요 _I  
:  string이 가장 많이 사용되고 json 문자열은 일반적으로

Interviewer :  Redis가 내부적으로 문자열을 어떻게 구현하는지 아십니까? _  
나 :  어 ~ 구체적인 구현이 명확하지 않기 때문에 Redis가 C 언어로 작성되었음을 이해합니다 ~

죽으 러 왔어요 ~~~

같은 경험을 가진 친구가 있습니까?


돌아와서 원리에 대한 Redis의 지식을 정리했는데, 인터뷰 경험의 가장 최근 요약이 되었기 때문에 오늘의 기사가 있습니다.

이 기사에서는 다음에 대해 설명합니다.

  • Redis 문자열 구현

  • Redis 스트링의 성능 이점

Redis 문자열 구현

Redis는 C 언어로 작성되었지만 C 언어 문자열을 직접 사용하지 않고 자체적으로 문자열 집합을 구현합니다. 그 목적은 속도와 성능을 향상시키는 것이며, Redis도 고성능을 위해 많은 노력을 기울이고 있음을 알 수 있습니다.

Redis는 SDS라고하는 간단한 동적 문자열 (Simple Dynamic String)을 구축했습니다.

1. SDS 코드 구조

struct sdshdr{  
    //  记录已使用长度  
    int len;  
    // 记录空闲未使用的长度  
    int free;  
    // 字符数组  
    char[] buf;  
};  

SDS? 도대체? 익숙하지 않은 친구는이 이름에 대해 의문을 가질 수 있습니다. 명사 일 뿐이고 상관 없습니다. 우리는 Redis의 디자인 아이디어를 감상하는 데 집중해야합니다. 한눈에 설명하기 위해 아래 그림을 그립니다.

Redis 문자열은 C 언어 문자열의 구현 규칙도 준수합니다. 즉, 마지막 문자는 널 문자입니다. 그러나이 널 문자는 len으로 계산되지 않습니다.

2. SDS 동적 확장 특성

SDS의 가장 강력하고 멋진 점은 Dynamic입니다. 길이를 동적으로 변경합니다. 예를 들면

위의 그림에서 보듯이 s1에는 처음에 5 개의 빈 자리 만 있고, 나중에 'world'의 6 개 문자를 추가해야하는데 이는 분명히 충분하지 않습니다. 지금이게 뭐야? Redis는 다음 세 가지 작업을 수행합니다.

  1. 크기가 충분한 지 계산

  2. 필요한 크기에 맞게 공간을 엽니 다.

  3. 사용 된 크기 len과 동일한 길이의 여유 공간을 엽니 다 (len <1M 인 경우) 길이가 1M 인 여유 공간을 엽니 다 (len> = 1M 인 경우).

지금까지 친구들이이 구현이 Java의 List 구현과 약간 유사하다고 생각하는 것을 보셨습니까? 그것을 읽은 후에는 더 좋아질 것입니다.

Redis 스트링의 성능 이점

  • 신속하게 문자열 길이 확인

  • 버퍼 오버 플로우 방지

  • 공간 할당 수를 줄이고 메모리 사용 효율성을 향상시킵니다.

1. 신속하게 문자열 길이 확인

위의 SDS 구조를보십시오.

struct sdshdr{  
    //  记录已使用长度  
    int len;  
    // 记录空闲未使用的长度  
    int free;  
    // 字符数组  
    char[] buf;  
};  

사용 된 문자 길이 len은 SDS에 저장되므로 문자열 길이를 얻고 싶을 때 len을 직접 반환 할 수 있으며 시간 복잡도는 O (1)입니다. C 언어 문자열을 사용하는 경우 문자열 길이 획득 함수 시간 복잡도는 O (n)이고 n은 문자 수입니다. 왜냐하면 처음부터 끝까지 (빈 문자 '\ 0'에) 순회되고 추가되기 때문입니다.

2. 버퍼 오버 플로우 방지

strcat을 사용하여 C 언어 문자열에 문자열을 추가 할 때 필요한 공간을 미리 열어 두어야하며, 공간을 열지 않으면 버퍼 오버플로가 발생하여 프로그램의 다른 코드에 영향을 미칠 수 있습니다. 아래 그림과 같이 문자열 s1 = "hello"와 문자열 s2 = "baby"가 있습니다. 이제 strcat (s1, "world")가 실행되고 실행 전에 s1에 대한 공간이 만들어지지 않았습니다. 버퍼 오버플로가 발생했습니다.

Redis의 경우 문자열이 추가 될 때마다 공간이 충분한 지 확인하기 때문에 버퍼 오버플로 문제가 없습니다. 각 추가 작업 전에 다음 작업이 수행됩니다.

  1. 크기가 충분한 지 계산

  2. 필요한 크기에 맞게 공간을 엽니 다.

3. 공간 할당 수를 줄이고 메모리 사용 효율성을 향상시킵니다.

문자열 추가 작업에는 메모리 할당 문제가 수반되지만 메모리 할당 문제에는 메모리 파티셔닝 알고리즘 및 시스템 호출이 포함되므로 자주 발생하면 성능에 영향을 미치므로 성능 지향 Redis에서는 절대 견딜 수 없습니다.

따라서 다음 두 가지 최적화 조치가 취해졌습니다.

  • 공간 및 할당

  • 불활성 공간 재활용

1. 공간 사전 할당

추가 작업의 경우 Redis는 충분한 공간을 열뿐만 아니라 다음 작업을 위해 사용되지 않은 공간 (사용 가능한 공간)을 미리 할당합니다. 사용하지 않은 공간 (free)의 크기는 수정 된 문자열 길이에 의해 결정됩니다.

수정 된 문자열 길이 len <1M 인 경우 len과 길이가 같은 사용되지 않은 공간이 할당됩니다 (사용 가능).

수정 된 문자열 길이 len> = 1M, 1M 미사용 공간 (여유)이 할당됩니다.

이 사전 할당 전략을 사용하면 할당 전에 기존 여유 공간이 충분한 지 확인하고 충분하면 열리지 않기 때문에 메모리 할당 수가 줄어 듭니다 ~

2. 비활성 공간 복구

위의 상황과는 달리 지연 공간 회수는 문자열 감소 작업에 적합합니다. 예를 들어 s1 = "hello world"문자열이있는 경우 s1에서 sdstrim (s1, "world") 작업을 수행합니다. 작업이 완료된 후 Redis는 축소 된 부분을 즉시 회수하지 않고 메모리가 필요한 다음 프로그램. 물론 Redis는 메모리 회수를위한 API도 제공하는데,이를 수동으로 앞뒤로 호출하여 일부 메모리를 축소하고 줄일 수 있습니다.

여기다 ~

다음에이 문제가 생기면 얘기 해봐요 하하하 ~

                                     ------------------------------------------- <END> ---- -----------------------------------

 

Xiaomu의 블로그

https://mp.weixin.qq.com/s?__biz=MzIyMDI5MzA3NQ==&mid=2247494059&idx=2&sn=3bdfdf5d9b663a52b009816043002126&chksm=97cc9b17a0bb1201abfdb3f772f1eb090db233f138cc398031efdb8b40bf14213a994d995ef7&mpshare=1&scene=1&srcid=0727In9avt5FM8XP0YlAJsNF&sharer_sharetime=1595827014131&sharer_shareid=57abc308ebeea6d6a3ae3cf44b76d275&rd2werd=1#wechat_redirect

 

추천

출처blog.csdn.net/qq_31653405/article/details/107657138