Redis中ziplist的实现二

添加 entry

ziplist 的添加过程大致如下:

  • 如果是一个新建的 ziplist,其中新增元素的时候,直接将 prevlen 设置为 0 即可

  • 如果是在中间位置新增,那么首先需要获取前一个 entry 的长度,因为后面的元素已经计算过了,因此直接拿来用即可

  • 如果是在尾部进行新增元素,那么需要计算其前一个元素的长度,因为 zlend 不会保存前一个最后一个尾节点的长度,因此需要在新增的时候计算

连锁更新

由于 ziplist 的设计,当前一个元素长度小于 254 的时候, prevlen 会以一个字节进行存储,但是当前一个元素大于 254 的时候,那么 prevlen 就会变成 5 个字节

阅读更多

Redis中ziplist的实现(一)

ziplist 是一个双向链表,但是不同于熟知的利用头指针和尾指针所形成的双向链表,ziplist 而是采用了一个特殊的实现

区别

普通的双向链表因为在每一个节点上都含有一个头节点和尾节点,所以在遍历的时候可以依次沿着每一个节点进行递归,而且在新增或者删除的时候,直接移动指针即可,并且每一个节点在内存中并不要求是连续的,只需要指针指向对应节点的内存地址即可。

但是 redis 使用的是内存,在内存满了的情况下就会造成 redis 的不可用,需要依据淘汰策略清理内存。

试想下如果 ziplist 像普通的双向链表一样,每一次新增一个 entry 都去申请一块新的内存,实现起来确实比较简单。

阅读更多

Redis中String的实现细节

String 是 Redis 中的基本数据结构之一,也是日常开发中使用最多的场景,例如秒杀扣库存,token缓存,详情缓存等,使用的频率还是比较高的,但是 Redis 中的 String 实现还是比较复杂的。

String 最底层的数据结构还是 char[],但是 Redis 在对数组进行封装的时候,做了一些细节上的优化

Redis 对象

在 Redis 中,每一个 Key 都可以称之为一个对象,Redis 包含了这个 Key 的类型,value 的内存地址,LRU 淘汰时间,引用计数等

1
2
3
4
5
6
7
struct RedisObject {
int4 type;
int 4 encoding;
int24 lru;
int32 refcount;
void *ptr;
}
阅读更多

Redis实现的分布式锁是完美的吗?

单实例

setnxRedis 官方提供的一个分布式原子性锁,它的实现利用了 Redis 在执行命令的时候是一个原子性操作,所以可以实现同一时间只有任务才能获取到锁。

当在同一个 redis 实例中进行加锁的操作的时候,如果加锁成功则会返回1,如果加锁失败的话,则是直接返回 0

1
2
127.0.0.1:6379> setnx 'redislock' 1
(integer) 1

如果此时另一个任务想进行加锁的话,则会返回0

阅读更多

Spring中AOP的探索与实践(一)之Redis多数据源切换

一般在项目的使用过程中,有时候为了减轻数据库的压力,从而将一部分数据缓存至Redis,但是随着业务量的增多。我们所需要的Redis服务器也会越来越多,就算不需要多个Redis数据源,那么在一个redis里面,切换不同的DB也是很麻烦的一件事情。

非AOP的一般的多数据源操作

在Redis的多数据源使用中,一般的方法是从配置文件中读取多个RedisProperties,读取到配置文件之后,将RedisProperties配置到RedisTemplate,然后每次使用的时候就通过不同的Template来调用Redis服务器。示例如下:

代码示例

Redis的配置类

阅读更多

spring连接redis的一些做法以及mybatis的一些感想

Redis启动

首先开启redis服务,windows的redis下载在github windows的redis下载地址,然后解压出来最后开启那个redis-server。
启动之后显示如下图:

spring配置:

配置

在Spring中也可以通过配置文件redis.properties配置,但是由于在这个项目中的配置文件已经太多了,所以选择使用类的方式进行配置:

阅读更多