Redis string of five data structures

Article Directory

table of Contents

Article Directory

1. What is Redis?

Second, use steps

1. Compile and install

2. Start and log in

Three, Redis data structure

Four, string type


1. What is Redis?

Redis ( Re Mote Di ctionary S erver), namely remote dictionary service, is an open source written in ANSI C language using the Key-Value-memory database.

Redis is widely used, such as Twitter, Blizzard Entertainment, Github, Stack Overflow, Tencent, Alibaba, JD
, Huawei, Sina Weibo, etc., and many small and medium-sized companies are also using it.

Second, use steps

1. Compile and install

git clone https://gitee.com/mirrors/redis.git -b 6.2cd redismakemake testmake install# 默认安装在 /usr/local/bin# redis-server 是服务端程序# redis-cli 是客户端程序

2. Start and log in

Modify redis.conf and put the configuration file in the /usr/local/bin/ directory (same level directory as redis-server)

-Configurable login password requirepass 123456

-Can be set to open as a daemon process: daemonize yes

Start redis:

cd /usr/local/bin./redis-server

Use the client to log in to redis:

cd /usr/local/bin./redis-cli -h 127.0.0.1 -a 123456

Three, Redis data structure

The overall internal storage structure of redis is a big dict, and the internal implementation is an array to implement hash. Among them, string/list/hash/set/zset are the values ​​of the array.

For address conflicts, the chain address method is used to resolve

Redis contains five commonly used data structures: string, list, hash, set, zset

Four, string type

The string type is the most basic data type in redis. It can store any form of string, including binary data (which can store pictures, etc.).

When the string length is less than 1M, double the expansion; if it exceeds 1M, only expand 1M each time;

The maximum length of the string is 512M.

Common operations:

# 设置 key 的 value 值SET key val# 获取 key 的 valueGET key # 执行原子加一的操作INCR key# 执行原子加一个整数的操作INCRBY key increment # 执行原子减一的操作DECR key# 执行原子减一个整数的操作DECRBY key decrement # 如果key不存在,这种情况下等同SET命令。 当key存在时,什么也不做SETNX key value# 删除 key val 键值对DEL key # 设置或者清空key的value(字符串)在offset处的bit值。SETBIT key offset value# 返回key对应的string在offset处的bit值GETBIT key offset# 统计字符串被设置为1的bit数.BITCOUNT key

String storage structure:

as the picture shows:

* When the string length is less than or equal to 20, and can be converted to an integer, use int type storage

* When the string length is less than or equal to 44, use embstr to store

* When the string length is greater than 44, use raw storage

Thinking: Why use 44 as the boundary (note: in versions before redis3.2, the boundary value is 39)? What are the benefits of doing this?

//server.htypedef struct redisObject {    unsigned type:4;    unsigned encoding:4;    unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or                            * LFU data (least significant 8 bits frequency                            * and most significant 16 bits access time). */    int refcount;    void *ptr;} robj; //sds.h 大于等于3.2版本struct __attribute__ ((__packed__)) sdshdr8 {    uint8_t len; /* used */    uint8_t alloc; /* excluding the header and null terminator */    unsigned char flags; /* 3 lsb of type, 5 unused bits */    char buf[];}; // 小于3.2版本struct sdshdr {    unsigned int len;    unsigned int free;    char buf[];}; //object.c/* Create a string object with EMBSTR encoding if it is smaller than * OBJ_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is * used. * * The current limit of 44 is chosen so that the biggest string object * we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc. */#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44 robj *createStringObject(const char *ptr, size_t len) {    if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT)        return createEmbeddedStringObject(ptr,len);    else        return createRawStringObject(ptr,len);}

As you can see from the redis source code, " The current limit of 44 is chosen so that the biggest string object we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc ."

That is, EMBSTR is suitable for the 64-byte allocation management area arena of the redis memory allocator jemalloc, which is related to the mechanism of jemalloc. In x64 system, sizeof(redisObject) = (4+4+24)/8 +4 + 8 = 16 byte, for string type, ptr points to sdshdr8 structure, sizeof(sdshdr8) = 1 + 1 +1 + X  + 1 = 4 byte, where the maximum value of X is 44 byte.

The redis memory allocator considers larger strings to be larger than 64 bytes; therefore, the size left for small strings is 64-16-3-1 = 44 (less than 3.2 version: 64-16-4-4-1 = 39) ;

The benefits of doing this:

Check the createStringObject function to know:

1. Embstr applies for or releases memory, only one operation is required (one-time allocation of robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr8)+len+1); ), and raw needs two times (one allocation for raw The sdshdr object, another time to allocate an object for redisObject (ptr points to the sds object)

2. embstr is continuous memory, read and write more efficient

Application scenarios:

accumulator:

# 统计阅读数 累计加1incr reads# 累计加100incrby reads 100

Distributed locks (this method is not safe and not recommended). Distributed locks are a big topic and will not be expanded here.

# 加锁setnx lock 1# 释放锁del lock

Bit operation

# 月签到功能 10001 用户id 202106 2021年6月份的签到 6月份的第1天setbit sign:10001:202106 1 1 # 计算 2021年6月份 的签到情况bitcount sign:10001:202106 # 获取 2021年6月份 第二天的签到情况 1 已签到 0 没有签到getbit sign:10001:202106 2