Redis总结

Redis官网
Redis命令参考
Redis源码Git地址
Redis版本 5.0.4

在这里插入图片描述

1 前言

Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster

Redis是一个开源的,基于内存处理的数据结构存储系统,可以作为数据库、缓存和消息处理。它支持的数据类型有字符串、哈希、列表、集合、有序集合、位图、Hyperloglog、地理位置和stream。同时还提供了复制、Lua脚本、LRU驱动事件、事务和不同级别的磁盘持久化功能,并通过哨兵和集群分区功能实现高可用。

由于Redis是基于内存的,其速度是很快的,每秒处理的请求可达十万次,可以通过redis-benchmark -n 100000 -q进行测试,官方文档结果如下:
在这里插入图片描述

  • 使用内存读写
  • 单线程
  • 异步非阻塞IO,多路复用

2 Redis基础

在这部分主要介绍Redis的基础知识,包括内容如下

  • Redis的安装
  • Redis的数据类型
  • Redis的操作命令
  • Java客户端Jedis的使用

2.1 Redis的安装

  • 下载Redis的压缩包
    在官方的下载页面中提供了Redis的非稳定版、稳定版和Docker的镜像三种,我们下载其稳定版的压缩包
    在这里插入图片描述

  • 解压编译
    tar zxf redis-5.0.4.tar.gz命令解压Redis的压缩包
    cd redis-5.0.4 进入redis目录执行make命令

  • 服务端和客户端的启动
    启动命令在src/目录下
    启动服务端 src/redis-server 。 想要在后台启动的话,需要将redis.conf配置文件中的daemonize参数设置为yes,默认为no
    在这里插入图片描述
    启动客户端src/redis-cli <-h host -p port>
    在这里插入图片描述

redis.conf是redis的配置文件,可以在这个里面进行相应启动参数的修改
想要redis服务端在非本地访问,需要设置 bind 0.0.0.0

2.2 通用命令

  • exists key 判断某个key是否存在
  • del key 删除指定的key
  • rename key newkey 重命名
  • keys * 列出所有的key 会遍历所有的key 会导致阻塞 线上环境禁用
  • dbsize 查看键个数
  • type key 判断指定key的数据类型
  • object encoding key 判断指定key的数据结构
  • flushdb 清空当前数据库
  • flushall 清空所有数据库
  • expire key seconds 为key设置过期时间
  • persist key 取消掉过期时间
  • ttl key 查看key的过期时间 秒
  • pttl key 返回key的过期时间 毫秒

2.3 数据类型及实现原理

在Redis中提供了多种数据类型,通过官方文档可以看到给出的有字符串、哈希、列表、集合和有序集合五种基本的数据类型,同时还有位图、HyperLogLogs和Streams(Redis 5新增)类型

Redis是一个key-value数据库,每设置一个键值对会创建一个dictEntry对象来进行存储,在该对象中会存储键和值的信息,key是使用的Redis自己实现的字符串SDS数据结构存储的,value是使用redisObject对象来存储的

  • dictEntry 可以在dict.h中找到对其定义,如下
typedef struct dictEntry {
    void *key;  // key的引用
    union {
        void *val; // value的引用
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next; // 下一个键值对的引用 用来解决hash冲突的情况,形成链表
} dictEntry;
  • redisObject可以在server.h中找到对其的定义,如下
typedef struct redisObject {
    unsigned type:4; // 对象类型 例如:string list hash set zset 
    unsigned encoding:4; // 底层编码
    unsigned lru:LRU_BITS; // 记录对象最后一次呗命令程序访问的时间  lru(24位时间)和lfu(8位访问频率16位访问时间)算法存储的样式有区别
    int refcount; // 引用计数  该值为0时对象所占的内存会被释放  可以用来实现对象共享
    void *ptr;  // 执行底层实现数据结构的指针
} robj;

数据的类型可以通过type key命令来查看,底层编码可以使用object encoding key命令进行查看
object idletime key 可以用来查看lru值 上次访问该key距离现在的时长

2.3.1 String 字符串

字符串是Redis的基础类型,该类型是二进制安全的,可以存储数字、文本、图片和视频等。

没有使用c语言的字符串,而是使用的自己实现的SDS(simple dynamic string 简单动态字符串)来存储。一个字符串的最大长度为512M,其数据结构的定义在sds.h中可以查看,其中定义了多种长度的sdshdr的结构如下

struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; // 长度
    uint8_t alloc; // 内存大小
    unsigned char flags; // 当前字符数组的属性
    char buf[]; // 字符串的值
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
2.3.1.1 SDS对C语言字符串的改进
  • 在SDS中维护了一个字符串长度的字段,在获取字符串长度时可以直接得到而不用进行遍历 时间复杂度将为0(1)
  • 在对SDS进行修改时,SDS的操作中会先检查空间是否满足,不满足的话会先进行扩容,可以避免缓冲区溢出
  • 在SDS中有内存预分配和惰性空间释放,减少在对字符串修改时对空间的分配次数
  • 二进制安全,SDS不仅能存文本还能存图片、视频等二进制数据
2.3.1.2 常用的命令
  • set key value 设置key 可以增加一些参数

    • EX seconds 为key设置过期时间 单位为秒 等同于expire key seconds的效果
    • PX millseconds 为key设置过期时间 单位为毫秒
    • NX 加上该参数只有当key不存在时才会添加成功
    • XX 加上该参数表示 只有当key存在时才能设置成功

    使用该命令可以实现分布式锁

  • setnx key value key不存在时设置成功

  • setex key seconds value 设置key同时制定存活时间

  • get key 获取一个key

  • getset key value 为key设置值并返回旧值

  • mset k1 v1 k2 v2 批量设置key

  • mget k1 k2 批量获取key的值

  • incr k key的值增加1

  • decr k key的值减1

  • incrby k num key的值增加指定的值

  • decrby k num key的值减少指定的值

  • strlen key 获取key的值的长度

  • append key value 拼接key的值

  • setrange key offset value 从索引为offset的位置其使用value进行覆盖

  • getrange key start end 获取指定范围的字符串

2.3.1.3 底层编码

字符串对象的编码有int、embstr和raw三种

  • int 存储的数据为整数,且长度不超过8个字节
  • embstr 存储的数据为长度小于44个字节的字符串或者长度超过8个字节的整数
  • raw 存储长度大于44字节的字符串

测试如下图所示
在这里插入图片描述
embstr和raw都是使用redisObject和sdshdr结构来存储字符串,raw编码会调用两次内存分配函数来创建这两个对象,embstr编码调用一次内存分配来分配一个包含这两个结构的连续的空间。

int和embstr编码在执行append操作会变为raw编码

2.3.2 hash 哈希

哈希可以用来存储多个简直对的映射。

2.3.2.1 常用命令
  • hset key field value 设置一个key的字段值
  • hmset key field1 value1 field2 value2 批量设置一个key的字段值
  • hsetnx key field value 当字段不存在时才设置
  • hget key field 获取一个key的某个字段值
  • hmget key field1 field2 批量获取某个key的字段值
  • hexists key field 判断一个key下面是否存在指定的字段
  • hdel key field1 field2 删除一个key下的某些字段
  • hlen key 获取一个key下的字段数量
  • hstrlen key field 获取一个key下摸个字段值的长度
  • hincrby key field num 为一个key下的某个字段值增加指定的值
  • hincrbyfloat key field num
  • hkeys key 获取某一key下的所有字段名
  • hvals key 获取key下的所有字段值
  • hgetall key 获取key下的所有字段名和值
2.3.2.1 内部编码

哈希的编码可以是ziplist或者hashtable

  • ziplist 压缩列表 键值对的键和值的字符串长度小于等于64字节且键值对数量小于512个

    ziplist.c中对压缩列表的解释如下:
    是一个经过特殊编码的双向链表,它不存储指向上一个链表节点和指向下一 个链表节点的指针,而是存储上一个节点长度和当前节 点长度,通过牺牲部分读写性能, 来换取高效的内存空间利用率,是一种时间换空间的思想。只用在字段个数少,字段值 小的场景里面。

ziplist的存储结构如下图所示:
在这里插入图片描述

  • zlbytes 记录整个压缩列表占用的内存字节数
  • zltail 记录压缩列表尾节点举例压缩列表起始地址有多少字节 通过该偏移量可以确定尾节点的地址
  • zllen 记录压缩列表包含的节点数量
  • entry 压缩列表的节点对象
  • zlend 用来标记压缩列表的尾端

列表节点对象的定义如下

typedef struct zlentry {
    unsigned int prevrawlensize; // 上一个节点占用的空间
    unsigned int prevrawlen; // 存储上一个节点大小所需要的空间
    unsigned int lensize; // 存储当前列表长度值所占用的空间
    unsigned int len; // 当前节点占用的长度
    unsigned int headersize; // prevrawlensize + prevrawlen
    unsigned char encoding; // 编码方式
    unsigned char *p; // 指向当前节点的起始位置
} zlentry;
  • hashtable 哈希表 当超出ziplist的范围后,底层编码会变为hashtable

在Redis中hashtable被称为字典,是通过数组加链表的结构实现的

dict.h中定义了这种数据结构,如下

/* This is our hash table structure. Every dictionary has two of this as we
 * implement incremental rehashing, for the old to the new table. */
typedef struct dictht {
    dictEntry **table; // 哈希表数组  其源码已在上面给出
    unsigned long size; // 哈希表大小
    unsigned long sizemask; // 哈希表掩码,用于计算索引值 等于size-1
    unsigned long used; // 该哈希表已有节点的数量
} dictht;

typedef struct dict {
    dictType *type; // 类型特定函数  指向dictType结构的指针
    void *privdata; // 私有数据  需要传递给特点函数的参数
    dictht ht[2];  // 哈希表  两个  为了rehash
    long rehashidx; // rehash索引  不在进行rehash时为-1
    unsigned long iterators; // 当前正在使用的迭代器的数量
} dict;

typedef struct dictType {
    uint64_t (*hashFunction)(const void *key); // 计算哈希值
    void *(*keyDup)(void *privdata, const void *key); // 复制键
    void *(*valDup)(void *privdata, const void *obj); // 复制值
    int (*keyCompare)(void *privdata, const void *key1, const void *key2); // 比较键
    void (*keyDestructor)(void *privdata, void *key); // 销毁键
    void (*valDestructor)(void *privdata, void *obj); //销毁值
} dictType;

其结构如下图所示
在这里插入图片描述
rehash过程

  • 为ht[1]哈希表分配空间,这个哈希表的空间大小取决于要执行的操作以及ht[0]当前包含的键值对数量
    • 扩容的情况:大小设置为第一个大于等于ht[0].used*2且为2的n次方的值
    • 收缩情况:大小设置为第一个大于等于ht[0].userd且为2的n次方的值
  • 将保存在ht[0]中的所有键值对rehash(重新计算键的哈希值和索引值)到ht[1]中 指定的位置
  • 释放ht[0] 将ht[1]设置为ht[0],并将ht[1]设置为空

渐进式rehash
当节点数量太大时,为了避免rehash对服务器性能造成影响,会采用分多次、渐进式地将ht[0]里面的键值对慢慢地rehash到ht[1]中,其过程如下
1、为ht[1]分配空间
2、将字典中的rehashidx设置为0
3、在rehash进行期间,每次对字典执行添加、删除、查找或者更新操作时,除了执行响应的操作外,还会将ht[0]上rehashidx索引上的键值对移动到ht[1]上,完成后,将rehashidx加一
4、当ht[0]上的所有数据都移动到ht[1]上后将rehashidx的值设置为-1

ziplist和hashtable编码之间的转化限制可以通过
list-max-ziplist-value 和 list-max-ziplist-entries参数设定

2.3.3 List 列表

列表用来存储一系列有序的字符串数据 有序 可重复 有索引

2.3.3.1 常用命令
  • lpush key value
  • lpushx key value
  • rpush key value
  • rpushx key value
  • lpop key value
  • rpop key value
  • lset key index value
  • lrange key start end
  • ltrim key start end
2.3.3.2 底层编码

在早期的版本中使用的ziplist和hashtable编码,3.2版本后使用的是quicklist编码,其结构源码在quicklist.h中定义如下:

typedef struct quicklist {
    quicklistNode *head; // 双向链表的头节点
    quicklistNode *tail; // 双向链表的尾节点
    unsigned long count; // 在所有ziplist中节点数
    unsigned long len; // 双向链表的节点数
    int fill : 16;              /* fill factor for individual nodes */
    unsigned int compress : 16; /* depth of end nodes not to compress;0=off */
} quicklist;

typedef struct quicklistNode {
    struct quicklistNode *prev; // 前一个节点
    struct quicklistNode *next; // 后继节点
    unsigned char *zl; // 执行ziplist
    unsigned int sz;  // 当前ziplist占用的字节
    unsigned int count : 16; // ziplist中存储了多少个元素 占16个字节
    unsigned int encoding : 2; // 是否采用LZF压缩算法
    unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;

如下图所示
在这里插入图片描述

2.3.4 set 集合

无序 元素不可重复

2.3.4.1 常用命令
  • sadd key v1 v2 v3 向集合中插入数据
  • smembers key 获取集合中的所有元素
  • scard key 获取集合中的元素数量
  • srandmember key count 从集合中随机获取count个数据 count省略取一个
  • spop key count 从集合中弹出count个数据 省略弹出一个
  • srem key v1 v2 从集合中删除指定的元素 可以指定多个
  • sismember key v 判断是否为集合的元素
  • smove source target v 从source集合中移动元素到target集合中
  • sdiff set1 set2 set3 多个集合的差集
  • sinter set1 set2 两个集合的交集
  • sunion set1 set2 两个结合的并集
  • sinterstore key set1 set2 交集存入一个新的集合
  • sdiffstore key set1 set2 差集存入一个新的集合
  • sunionstore key set1 set2 并集存入一个新的集合
2.4.4.2 底层编码

底层编码为intset或者hashtable,当为纯整数且数量小于513个时使用的是intset编码实现,底层是一个整数集合,否则使用hashtable

2.3.5 zset 有序集合

元素不可重复 有序 通过制定score排序

2.3.5.1 常用命令
2.3.5.2 底层编码

有序集合的底层编码使用的是ziplist或者skiplist实现

2.3.6 其他类型数据

前面几部分我们介绍了Redis中的5种基本数据类型,除了这几种类型,在Redis中还有另外的集中类型,如下

  • Bitmap 位图
  • HyperLogLogs
  • geo 地理位置
  • stream
2.3.6.1 位图

位图不是实际的数据类型,而是在String类型上定义的一组面向比特的操作,我们可以使用这种操作对一个字符串的某位的字节数进行修改(0或1)。

常用命令

  • bitcount key
  • setbit
  • getbit
  • bitop
  • bitpos
  • bitfield
2.3.6.2 HyperLogLog

HyperLogLog是一种概率统计的数据结构,用于对数据集合中的数据进行唯一性统计。

2.3.6.3 地理位置

地理位置是一种特殊的有序集合,存储经纬度、名称、地理空间等信息。

2.4 Redis配置

在Redis的安装目录下有redis.conf文件,这是Redis的配置文件

2.5 Java客户端

Redis提供了大量的客户端支持

Java的客户端也有很多个,如下图
在这里插入图片描述
Jedis客户端的使用

  • 添加Jedis的Maven依赖
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.1.0</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>
  • 客户端使用
    通过服务端的ip和端口创建一个Jedis对象,使用该对象对redis进行操作,代码如下
public static void main(String[] args) {
    Jedis jedis = new Jedis("127.0.0.1", 6379);

    jedis.set("name", "xiehua");
    System.out.println(jedis.get("name"));
    
}

3 发布/订阅

在Redis中提供了发布/订阅模式,过程是消费者订阅所需的频道,生产者向频道中发布消息,这样实现了生产者和消费者之间的解耦。

3.1 相关命令

  • subscribe channel1 channel2 订阅频道,可以指定多个
  • psubscribe pattern 使用匹配规则订阅频道 一个字符 * 多个字符
  • publish channel message 向频道中发布消息
  • unsubscribe channel1 channel2 取消订阅某些频道
  • punsubscribe pattern 使用匹配规则取消订阅频道
  • pubsub channels pattern 列出满足匹配规则的频道 没有匹配规则列出所有
  • pubsub numsub channel1 channel2 返回频道的订阅数量 支持同时查询多个频道

命令演示如下所示:
在这里插入图片描述

4 事务

事务相关的命令

  • multi 开始事务
  • exec 提交事务
  • discard 取消事务
  • watch key 监视一个键 当有其他客户端对该值进行修改后,事务会被打断 演示如下
    在这里插入图片描述

Redis中的事务和Mysql中的事务是有区别的,在Redis事务中若发生异常,其他的操作是不会进行回滚的,这样发生的脏数据需要手动进行处理,因此无法通过Redis事务来保证多个操作的原子性,演示如下:
在这里插入图片描述
在上面的演示中我们创建了一个字符串键和一个哈希键,在事务中均使用set命令修改这两个键,当提交事务后,发现字符串键已被修改

5 持久化

为了防止在Redis服务宕机后数据丢失的问题,Redis里提供了RDB和AOF两种持久化方式。

5.1 RDB持久化

RDB是Redis的默认持久化方案。将内存的数据生成一个.rdb文件,在服务重启时加载该rdb文件进行数据恢复。

有如下配置

  • dbfilename 文件名称 默认为dump.rdb
  • dir 文件存储路径
  • rdbcompression 是否开启压缩 开启可以节省存储空间,但会消耗一些CPU 默认开启
  • rdbchecksum 使用CRC64算法进行数据校验 默认开启

5.1.1 RDB的快照生成方式

  • 手动触发
    • save 该命令在生成快照时会阻塞当前服务器,Redis不能处理其他命令
    • bgsave 使用该命令Redis会在后台异步进行快照操作,Redis服务器还能处理其他请求
  • 自动触发
    • 配置文件制定规则 在配置文件的SNAPSHOTTING下有触发频率的配置,其格式为save <seconds> <changes> ,默认配置如下

      save 900 1 900秒内至少有一个key被修改
      save 300 10 300秒内至少有10个key被修改
      save 60 10000 60秒内至少有10000个key被修改

    • 调用shutdown命令

5.1.2 RDB持久化的特点

优点

  • RDB是一个紧凑的文件,保存了Redis在某个时间点上的数据集,适合用于进行备份和灾难恢复
  • 生成RDB文件的时候,Redis主进程会fork()一个子进程来处理备份工作,主进程不需要进行任何磁盘IO操作
  • RDB在恢复数据的速度要快

缺点

  • 无法做到实时持久化
  • 意外发生宕机的情况会吊事最后一次快照之后的所有修改

5.2 AOF持久化

AOF持久化默认是关闭的,该持久化方式是通过记录每个写操作,将其保存到文件中,在Redis重启时会根据日志文件的内容把写指令执行一遍。

5.2.1 开启AOF

通过redis.conf中的appendonly参数进行开启,通过appendfilename参数设置文件名,文件路径也是由dir参数指定

触发条件由appendfsync参数设置,有如下三种

  • no 由操作系统保证数据同步 速度快 不安全
  • always 每次写入都执行同步 效率低 发生宕机最多丢失一个命令的数据
  • everysec 每秒同步一次 可能会丢失一秒的数据 通常使用该方式

5.2.2 重写机制

由于AOF持久化是通过记录操作指令的方式工作的,随着时间的推迟,生成的AOF文件会越来越大,为了解决这个问题,Redis中增加了重写机制,当文件达到一定大小后,Redis就会对其进行重写,只保留可以恢复数据的最小指令集。

  • auto-aof-rewrite-percentage 当目前aof文件大小超过上一次重写的aof文件大小的百分比进行重写。默认为100
  • auto-aof-min-size 指定允许进行重写操作的最小大小,避免达到百分比但文件很小的情况进行重写 默认为64m

5.2.3 AOF持久化的特点

优点

  • AOF持久化的方法提供了多种同步频率,对数据的完整性保证更高,采用默认的同步频率,最多丢失1秒的数据

缺点

  • AOF的文件较大
  • 在高并发情况下,RDB比AOF具有更好的性能

5.3 持久化方式的选择

了解了RDB和AOF两种持久化策略的特点后,我们应该如何选择呢

  • 在对数据完整性要求不是太高的情况下,优先使用RDB进行持久化
  • 一般情况下两种同步方式同时开启,这种情况下,Redis重启的时候会优先载入AOF文件进行数据恢复

6 内存回收

在这部分我们了解一下Redis的内存回收,在Redis中内存回收包含两类

  • 设置了过期时间的键的删除
  • 内存使用达到上限触发的内存淘汰

6.1 过期键删除策略

我们可以通过expire key命令为key设置存活时间,这个键是是何时真正的删除并释放内存呢?在这一部分我们将对其进行介绍

在说Redis的过期键删除策略前我们先来了解下三种删除方式,如下:

  • 定时删除 在设置键的过期时间的同时,创建一个定时器,当键的存活时间到后立即删除

    能够及时的释放内存,但当过期键比较多时会占用较长的cpu资源,影响服务器的响应时间和吞吐量

  • 惰性删除 每次从键空间获取键时,判断取得的键是否过期,如果过期的话,就删除该键,否则返回

    不会占用过多的cpu资源,但有些键一直不被访问的情况下,会一直占用内存

  • 定期删除 每隔一段时间,程序对数据库进行一次检查,删除里面过期的键

    这种方式是前两种方式的折中方案,但需要根据情况设置合理的删除量和执行频率

6.1.1 Redis中的过期键删除策略

在前面我们了解了三种删除策略的特点,那么在Redis中是使用的哪种策略呢?

官网文档给出的说明如下:
在这里插入图片描述
通过官网的说明,我们可以看出在Redis中使用的是惰性删除和定期删除两种策略,通过这两种策略的配合使用,可以在使用CPU时间和占用内存之间取得平衡

1、Redis中惰性策略的实现
Redis中惰性删除策略的逻辑在db.c#expireIfNeeded方法中定义,其源码如下

int expireIfNeeded(redisDb *db, robj *key) {
    if (!keyIsExpired(db,key)) return 0;

    if (server.masterhost != NULL) return 1;

    server.stat_expiredkeys++;
    propagateExpire(db,key,server.lazyfree_lazy_expire);
    notifyKeyspaceEvent(NOTIFY_EXPIRED,
        "expired",key,db->id);
    return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :
                                         dbSyncDelete(db,key);
}

2、Redis中的定期删除策略

从上面的文档截图中我们可以看到在Redis中过期键的定期删除过程为

  • 1、从设置了过期时间的键中抽取20个
  • 2、删除其中已经过期的键
  • 3、如果有超过25%的键过期了会重复执行该步骤一

6.2 Redis淘汰策略

在Redis中我们可以通过maxmemory参数来配置Redis可以使用的最大内存,当达到该值后会对内存进行回收,支持的淘汰策略如下:

  • volatile-lru 设置了过期时间的中最近最少访问 Least Recently Used
  • allkeys-lru 最近最少访问
  • volatile-lfu 设置了过期时间中最不常用的 Least Frequently Used
  • allkeys-lfu 最不常用的
  • volatile-random 设置了过期时间中随机
  • allkeys-random 随机
  • volatile-ttl 根据过期时间删除
  • noeviction 不进行淘汰,无法再进行写操作

通过maxmemory-policy参数指定 默认为noeviction

7 主从复制

在Redis中,我们可以通过执行slaveof命令,让一个服务器去复制另一个服务器,我们称被复制的服务器为主服务器,复制操作的服务器称为从服务器,从服务器只能进行读操作,示例如下
在这里插入图片描述
replicaof/slaveof ip port 使其成为某个服务的从节点
replicaof/slaveof no one 使其脱离节点
info replicaton 查看集群信息

7.1 实现原理

  • 当一个服务器称为某个服务的从服务后,首先需要同步主服务上的数据,这步是全量复制。主节点通过bgsave命令在本地生成一份RDB文件,并将该文件发送给从节点,从节点首先清除自己的旧数据,然后使用该RDB文件加载数据
  • 之后在主节点的更新操作会通过命令传播的方式发送给从服务器
  • 从服务器宕机后重新连接主节点,此时无需执行全量复制,在从服务器中会存储一个master_repl_offset的偏移量数据,只需同步之后的操作即可

8 Sentinel 哨兵

Sentinel是Redis的高可用解决方案

9 Redis集群

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
森林防火应急联动指挥系统是一个集成了北斗定位/GPS、GIS、RS遥感、无线网络通讯、4G网络等技术的现代化智能系统,旨在提高森林火灾的预防和扑救效率。该系统通过实时监控、地图服务、历史数据管理、调度语音等功能,实现了现场指挥调度、语音呼叫通讯、远程监控、现场直播、救火人员生命检测等工作的网络化、智能化、可视化。它能够在火灾发生后迅速组网,确保现场与指挥心的通信畅通,同时,系统支持快速部署,适应各种极端环境,保障信息的实时传输和历史数据的安全存储。 系统的设计遵循先进性、实用性、标准性、开放性、安全性、可靠性和扩展性原则,确保了技术的领先地位和未来的发展空间。系统架构包括应急终端、无线专网、应用联动应用和服务组件,以及安全审计模块,以确保用户合法性和数据安全性。部署方案灵活,能够根据现场需求快速搭建应急指挥平台,支持高并发视频直播和大容量数据存储。 智能终端设备具备三防等级,能够在恶劣环境下稳定工作,支持北斗+GPS双模定位,提供精确的位置信息。设备搭载的操作系统和处理器能够处理复杂的任务,如高清视频拍摄和数据传输。此外,设备还配备了多种传感器和接口,以适应不同的使用场景。 自适应无线网络是系统的关键组成部分,它基于认知无线电技术,能够根据环境变化动态调整通讯参数,优化通讯效果。网络支持点对点和点对多点的组网模式,具有低功耗、长距离覆盖、强抗干扰能力等特点,易于部署和维护。 系统的售后服务保障包括安装实施服务、系统维护服务、系统完善服务、培训服务等,确保用户能够高效使用系统。提供7*24小时的实时故障响应,以及定期的系统优化和维护,确保系统的稳定运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值