Redis 设计与实现(8-数据库)
底层结构Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中,db数组的每个项都是一个redis.h/redisDb结构,每个redisDb结构代表一个数据库:
struct redisServer{ //一个数组,保存着服务器中的所有数据库 redisDb *db; //服务器的数据库数量 int dbnum;};
在初始化服务器时,程序会根据服务器状态的dbnum属性来决定应该创建多少个数据库。
dbnum属性的值由服务器配置的database选项决定,默认情况下,该选项的值为16。
数据库切换每个Redis客户端都有自己的目标数据库,每当客户端执行数据库写命令或者数据库读命令的时候,目标数据库就会成为这些命令的操作对象。
默认情况下,Redis客户端的目标数据库为0号数据库,但客户端可以通过执行SELECT db命令来切换目标数据库。
在服务器内部,客户端状态redisClient结构的db属性记录了客户端当前的目标数据库,这个属性是一个指向redisDb结构的指针: ...
Redis 设计与实现(7-对象)
Redis并没有直接使用SDS、链表、字典、跳跃表、整数集合、压缩列表等这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这个系统包含字符串对象、列表对象、哈希对象、集合对象和有序集合对象这五种类型的对象,每种对象都用到了至少一种前面的数据结构。
Redis在执行命令前,可以根据对象的类型来判断一个对象是否可以执行给定的命令。
针对不同场景,为对象设置多种不同的数据结构实现,优化使用效率。
Redis对象系统实现了基于引用计数技术的内存回收机制。
通过引用计数技术实现了对象共享机制。
Redis的对象带有访问时间记录信息,用以过期清除。
对象的类型与编码每次在Redis的数据库中新创建一个键值对时,至少会创建两个对象,一个对象用作键值对的键(键对象),另一个对象用作键值对的值(值对象)。
Redis中的每个对象都由一个redisObject结构表示,该结构中和保存数据有关的三个属性分别是type属性、encoding属性和ptr属性:
typedef struct redisObject{ //类型 unsigned typ ...
Redis 设计与实现(6-压缩列表)
压缩列表(ziplist)是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项/当一个哈希键只包含少量键值对,并且每个列表项/每个键值对的键和值 要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。
压缩列表的构成压缩列表是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构。一个压缩列表可以包含任意多个节点(entry),每个节点可以保存一个字节数组或者一个整数值。
压缩列表组成部分说明:
类型
长度
用途
zlbytes
uint_32
4
记录整个压缩列表占用的内存字节数,在对压缩列表进行内存重分配或计算zlen的位置时使用。
zltail
uint_32
4
记录压缩列表表尾节点距离压缩列表的起始地址有多少字节:通过这个偏移量,程序无需遍历整个压缩列表就可以确定表尾节点的地址。
zllen
uint_16
2
记录了压缩列表包含的节点数量:当这个属性的值小于uint16_max(65535)时,这个属性的值就是压缩列表包含节点的数 ...
Redis设计与实现(5-整数集合)
整数集合(intset)是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现。
整数集合的实现整数集合(intset)是Redis用于保存整数值的集合抽象数据结构,它可以保存类型为int16_t、int32_t或者int64_t的整数值,并且保证集合中不会出现重复元素。
每个intset.h/intset结构表示一个整数集合:
typedef struct intset{ //编码方式 uint32_t encoding; //集合包含元素数量 uint32_t length; //保存元素的数组 int8_t contents[]} intset;
contents数组是整数集合的底层实现:整数集合的每个元素都是contents数组的一个数组项(item),各个项在数组中按值的大小从小到大有序地排列,并且数组中不包含任何重复项。
length属性记录了整数集合包含的元素数量,即contents数组的长度。
虽然intset结构将conten ...
Redis设计与实现(4-跳跃表)
跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。
跳跃表支持平均O(logN)、最坏O(N)复杂度的节点查找,还可以通过顺序性操作来批量处理节点。
Redis使用跳跃表作为有序集合键的底层实现之一:
有序集合包含的元素数量比较多。
有序集合中元素的成员(member)是比较长的字符串。
Redis只在两个地方用到了跳跃表:
实现有序集合键。
在集群节点中用作内部数据结构。
跳跃表实现Redis的跳跃表由 redis.h/zskiplistNode 和 redis.h/zskiplist 两个结构定义,其中zskiplistNode结构用于表示跳跃表节点,而zskiplist结构则用于保存跳跃表节点的相关信息。
跳跃表节点跳跃表节点的实现由redis.h/zskiplistNode结构定义:
typedef struct zskiplistNode{ //层 struct zskiplistLevel { //前进指针 ...
Redis学习笔记 (1)
第一次接触Redis,已经记不清是什么时候了,那时候对它的唯一印象就是它是数据库,还能做缓存。对于它的底层,数据结构什么的一概不知,更不用说什么缓存,消息通知什么的了。前段时间又系统的看了一遍Redis视频教程和书本教程,在此做个记录。毕竟好记性不如烂笔头。此为开篇。
初识RedisRedis是基于key-value的存储服务系统,支持多种数据结构,并且是开源的。
特性
速度快
Redis速度之所以快的最根本原因,是因为其数据存在内存中。
持久化
以异步的方式将数据保存在硬盘上
RDB
AOF
多种数据格式
字符串
list
哈希
集合
有序集合
Bitmaps:位图
HyperLogLog:超小内存唯一值计数
GEO:地理信息定位
多功能
发布订阅
事务
Lua脚本
pipeline
安装/启动安装# Linux# 获取安装包wget 安装包链接# 解压tar -zxvf 安装包# 添加软连接ln -s 安装包 redis# 安装cd redismake && make install
Redis目录可执行文件说明:
...
Python Supervisor使用教程
supervisor简介
Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems.
It shares some of the same goals of programs like launchd, daemontools, and runit. Unlike some of these programs, it is not meant to be run as a substitute for init as “process id 1”. Instead it is meant to be used to control processes related to a project or a customer, and is meant to start like any other program at boot time.
官方文档:点击此处
以上摘自 ...
重拾Hexo主题博客
去年6月份,接触到了hexo静态博客,一时兴起之下,就跟着教程搭了一个。但只是搭了一个,之后就再也没用过了。一个月之前我便在思考重试起我的博客网站,但依然没想好是使用前后端分离,还是直接使用模板语言,亦或是hexo。一个月后,终于决定还是使用hexo搭建,一时多熟悉一下hexo,第二也是最重要的一点是,想要借助静态博客,锻炼一下我的markdown写作能力,好了,正文开始,此篇为记录下搭建过程。本文不介绍详细安装过程
工具/环境搭建安装nodejs由于hexo基于nodejs,所以在使用hexo之前需要安装nodejs,安装nodejs方法这里不再赘述,各位看官直接网搜教程即可PS:尽量安装最新/稳定版本的nodejs
安装hexo安装好node之后,就可以安装hexo了。打开Terminal,输入npm i hexo-cli -g,等待安装结束后,hexo便安装好了。如果嫌弃安装速度过慢的话,可以配置一下npm的国内下载源,这里不再赘述,直接搜淘宝npm
使用github安装git没有过github经历的朋友,先去网上搜一下github(国内访问可能会慢),跟着网 ...