二、Redis基础数据结构-string
1、说明
字符串string是Redis最简单的数据结构,它的内部表示就是一个字符数组。Redis的字符串是动态字符串,是可以修改的字符串,内部结构的实现类似于java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。
2、内部实现
Redis内部构建了一个简单的动态字符串来存储,数据结构为:
1 struct SDS { 2 // 字符串的长度 3 T len; 4 // 分配数组的长度 5 T capacity; 6 // 字符数组 7 byte[] buf; 8 }
在数据结构中,长度的类型使用的是泛型,而没有直接用int,这是因为当字符串比较短时,可以使用byte和short来表示。Redis字符串存储结构示意图:

最后一个'\0'为空字符串,不计算在len长度中,这样做是为了遵循C语言字符串的实现规则。
当Redis字符串长度变大时:
- 判断capacity长度是否足够存储新增的字符,如果满足,则无需扩容,否则进行扩容;
- 如果len<=1MB,则加倍进行扩容,即capacity*2,然后继续进行判断;
- 如果len>1MB时,则1次只会增加1MB的空闲空间,然后继续进行判断;
- 字符串长度最大扩容到512MB
当Redis字符串进行缩减时,不会立即回收减少的部分,而是会分配给下一个需要内存的程序。
3、字符串命令
| 命令 | 描述 |
| SET key value | 设定指定key的值 |
| GET key | 获取指定key的值 |
| SETRANGE key offset value | 从偏移量offset开始重写value的值。如当前key为hello,SETRANGE key 2 x后的value值为hexlo |
| GETRANGE key start end | 返回key中字符串值的下标从start到end的子字符串 |
| GETSET key value | 将给定key的值设置为value,并返回key的旧值 |
| SETBIT key offset value | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。value只能是0或者1 |
| GETBIT ket offset | 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。 |
| MSET key1 value1 [key2 value2 ...] | 同时设置多个key-value对 |
| MGET key1 [key2...] | 获取所有给定key的值 |
| SETEX key seconds value | 设置key的值,并设置key的有效时间为seconds秒 |
| SETNX key value | 只有在key不存在时,才设置key的值 |
| STRLEN key | 返回key存储的字符串值得长度 |
| INCR key | 将key中存储的数字加1,默认从0开始 |
| INCRBY key increment | 将key存储的值增加上指定的增量increment |
| INCRBYFLOAT key increment | 将key存储的值增加上指定的浮点增量increment |
| DECR key | 将key中存储的数字减1,默认从0开始 |
| DECRBY key increment | 将key存储的值减少指定的增量increment |
| APPEND key value | 如果key存在并且是一个字符串,则将value的值追加到key原来值得后面。如果key不存在,则相当于set操作 |
4、应用场景
4.1 计数器
incr和decr的命令是将key中存储的数字的值加1和减1,这2个操作具有原子性,因此可以用来计算。如:评论数,点赞数,分享数等。
4.2 分布式锁
setnx的作用是当key不存在时,设置值并返回1,当key已经存在,不设置值并返回0,而这个操作也是原子性的,所以可以用来做分布式锁。返回1表示获得到了锁,返回0表示没有获得到锁;然后使用del删除key来释放锁。可以同时给key设置一个过期时间,这样当del删除失败时,也可以保证锁能够释放。
4.3 缓存
set操作可以存储值,可以将数据对象进行序列化操作后,存储起来作为缓存使用。
4.4 用户签到记录
可以使用位图(byte数组)来记录用户的签到记录,每天的签到记录只占据一个位,365天就是365个位,46个字节就可以完全容纳下。

浙公网安备 33010602011771号