asp。net网站开发,四川省安监站网址,网站怎么推广出去比较好,财政网站平台建设不足如果源码不编译#xff0c;是无法实现自动跳转的#xff0c; Redis在win上编译有点麻烦#xff0c;我是使用的CentOS环境#xff0c;Clion编译 编译完就可以直接通过shell连接Redis server了 server.c 中放的是就是主类 #xff1a;6000多行左右是入口main()函数位置 Red… 如果源码不编译是无法实现自动跳转的 Redis在win上编译有点麻烦我是使用的CentOS环境Clion编译 编译完就可以直接通过shell连接Redis server了 server.c 中放的是就是主类 6000多行左右是入口main()函数位置 Redis的使用
通过redis.conf 文件的如下位置 配置 Redis有多少个数据库 select 0 select 1对应就是数据库的序号16个数据库对应0-15下标
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 下图就是数据库的结构:
其中最重要的一项就是存放该数据库key-value对的715行 dict 类型的 *dict指针 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
dict 数据类型如下定义 83行有两个dictht 类型的数组就是对应存放 老HashTable 和 新扩容的HashTable 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
62hashFunction() 给出 key 求对应的哈希值
65keyCompare() 比较两个Key是否一致是否出现冲突一致的话执行后续逻辑操作 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
HashTable的数据结构 Redis 底层设计方式Redis底层 如何 管理数据
Redis通过 HashTable 来 存放数据
我们知道 Redis 维护的是一个个 key-value 的项entry而组织存放这些entry的数据结构是 HashTableHashTable是一个数组
通过对 entry 中 key 的 hash() 处理并且按照HashTable大小取模这样把key对应到为一个int 值。该 int 值作为下标HashTable[i] 中就存放 该entry 的 value 内容的地址即存放的是指向value值存放空间的指针注意HashTable中存的是地址不是把entry直接存进去了
由于hash函数会导致哈希冲突即不同的key可能会哈希到同一个值Redis 通过拉链法即在HashTable的值指向一个个 结构体结构体内容包括key值value的地址和 next指针用于指向下一个哈希到相同位置的entry条目同时每次出现哈希冲突新的entry对应的结构体以头插法的方式插入到链表头部新头插的entry可能会在最近被访问的概率大
而哈希冲突越来越频繁的时候拉链越来越长找到一个对应的entry时间也越来越长此时HashTable就会考虑扩容HashTable扩容的条件是若出现一条拉链链表的长度HashTable的长度那么HashTable扩容。
HashTable扩容的方式成倍扩容原来HashTable长度是 8 扩容后会开辟一个新的大小为8*216的空间放置扩容的HashTable。
而后将旧的HashTable中的拉链上的各个entry结构体重新执行哈希函数插入到扩容后的HashTable中。这个操作就被称为 rehash
主动渐进式将entry移动到新的HashTable中操作是不管get set 等任何访问HashTable的操作只要访问了HashTable就按顺序移动一个hash槽一个哈希槽对应所有被哈希函数处理后对应到该位置的entry内的所有内容。这么做是由于我们使用Redis就是为了加速而大批量新旧HashTable的数据转移会影响Redis正常功能因此要渐进式移动数据。
在渐进式移动HashTable时调用get()要求获得某个数据的value执行顺序 先去旧HashTable寻找找不到再去新的HashTable寻找
调用set()时直接向新的HashTable中插入这就是为啥访问get时会出现key找不到是因为get的value是新set的数据已经被插入到新的HashTable中了 Redis 的 key 数据类型
Redis 在使用时key可以是 整形、浮点、字符串 、音频视频等但实际上Redis服务器端会将无论是什么数据类型的key都转换成 String对象
SDS数据类型
【SDS相较于char[] 做了哪些优化】
一减少len这个属性占的空间
3.2和3.2版本之前SDS 数据结构用 int 来描述SDS的buf[]长度
int占4个字节但是buf[]长度可能只有10个造成SDS实例空间浪费
结局方案是Redis6版本提出了SDS 新的数据类型实现sdshdr5
结构中包括char类型的 flag和 存放内容的buf[]
char占8字节前3位用于表明这是个SDS的数据类型后5位用来指示buf[]的长度 啥叫SDS数据类型因为SDS为了不同长度的buf定义了多种不同的 sdshdrX 数据类型有sdshdr5 , sdshdr8 等等 二预分配、懒回收
定义字符串 ss lalala时系统会自动 malloc出6个char大小存放
此时我们想在后面加一个字符就得重新malloc()malloc()函数调用要很长的时间因此每次出现扩容需求的时候若扩容内容1M : 倍增原来的buf数组长度若1M则满足新的buf数组的长度后在追加1M的大小
SDS的free变量(在6版本的Redis中改了个名字 叫 alloc还是一个意思一个用法)就是记录这个每次与分配后还剩余的空间free也因为buf的长度不同 优化为了 uint8_t 或者 uint16_t
三Redis 赋值buf[]时也会 以 \0结尾为了兼容C语言其实就是为了少写点函数用用C语言的函数
四二进制安全即使buf[]中出现 \0也没关系不会被处理为内容结束