为了便于操作,Redis采用redisObjec结构来统一五种不同的数据类型,这样所有的数据类型就都可以以相同的形式在函数间传递而不用使用特定的类型结构。同时,为了识别不同的数据类型,redisObjec中定义了type和encoding字段对不同的数据类型加以区别。简单地说,redisObjec就是string、hash、list、set、zset的父类,可以在函数间传递时隐藏具体的类型信息,所以作者抽象了redisObjec结构来到达同样的目的。
String类型
为什么采用简单动态字符串作为redis的默认字符串?
C语言没有Java里面的String类型,只能是靠自己的char[]来实现,字符串在 C 语言中的存储方式,想要获取 「Redis」的长度,需要从头开始遍历,直到遇到 ‘\0’ 为止。所以,Redis 没有直接使用 C 语言传统的字符串标识,而是自己构建了一种名为简单动态字符串 SDS(simple dynamic string)的抽象类型,并将 SDS 作为 Redis 的默认字符串。
3大物理编码方式: int 、embstr 、raw
int :保存long型的64位有符号整数
注:只有整数才会使用int,如果是浮点数,redis内部讲浮点数转化为字符串值再保存。
embstr:嵌入式的String,代表embstr格式的SDS(简单动态字符串),保存长度小于44字节的字符串。
raw:保存长度大于44字节的字符串
Hash数据结构
Java中,JDK8之前采用的是数组+链表的方式,JDK8之后采用的是数组+链表+红黑树的方式。HashMap默认初始化大小为16,之后每次扩容,容量变为原来的2倍。JDK1.8之后HashMap当链表长度大于阈值(默认8),将链表转化为红黑树(此时要求当前数组的长度大于64,若小于则优先选择数组扩容)
ConcurrentHashMap和HashTable:
ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同。
JDK1.7 的 ConcurrentHashMap 底层采用 分段的数组+链表 实现,JDK1.8 采用的数据结构跟 HashMap1.8 的结构一样,数组+链表/红黑二叉树。Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 数组+链表 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的;
JDK1.7 ConcurrentHashMap对整个数组进行了分段分割,每把锁只锁容器中其中一部分数据,JDK1.8ConcurrentHashMap直接使用Node数组+链表+红黑树实现,并发控制采用synchronized和CAS操作。
Segment继承了ReenTrantLock,所以是一种可重入锁。Java 8 中,采用node+cas+synchronized保证线程安全,锁粒度更细,synchr