1.概述

1.1 传统数据库存在的问题

1.数据库压力过大
由于用户量增大,请求数量也随之增大,数据压力过大
2.数据不同步
多台服务器之间,数据不同步
3.传统锁失效
多台服务器之间的锁,已经不存在互斥性了。

1.2 NoSQL介绍

image.png
Redis就是一款NoSQL
Redis是K-V的内存存储 键值对类型
NoSQL -> 非关系型数据库 -> Not Only SQL。
除了关系型数据库都是非关系型数据库。
NoSQL只是一种概念,泛指非关系型数据库,和关系型数据库做一个区分。

类型 部分代表 特点
列存储 Hbase
Cassandra
Hypertable
顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。
文档存储 MongoDB
CouchDB
文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。
key-value存储 Tokyo Cabinet / Tyrant
Berkeley DB
MemcacheDB
Redis
可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能)
图存储 Neo4J
FlockDB
图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。
对象存储 db4o
Versant
通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。
xml数据库 Berkeley DB XML
BaseX
高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。

1.3 Redis简介

  • 有一位意大利人,在开发一款LLOOGG的统计页面,因为MySQL的性能不好,自己研发了一款非关系型数据库,并命名为Redis Salvatore。
  • Redis(Remote Dictionary Server)即远程字典服务,Redis是由C语言去编写,Redis是一款基于Key-Value的NoSQL,而且Redis是基于内存存储数据的,Redis还提供了多种持久化机制,性能可以达到110000/s读取数据以及81000/s写入数据,Redis还提供了主从,哨兵以及集群的搭建方式,可以更方便的横向扩展以及垂直扩展。

    2.安装

    2.1 Linux原生安装Redis

    a.找到Redis的下载地址
    进入官网找到下载地址 https://redis.io/download
    image.png
    b.下载Redis
    cd /usr/local
    wget https://download.redis.io/releases/redis-6.2.1.tar.gz
    image.png
    c.解压Redis
    tar -zxf redis-6.2.1.tar.gz
    image.png
    d.编译
    cd redis-6.2.1
    make
    需要一段时间
    image.png
    ps:如果编译报错,可能缺乏c语言编译环境,可以通过以下命令检测
    image.png
    cc -v
    image.png
    如果报cc不是命令,那就是缺乏环境
    yum -y install gcc
    e.安装
    make install
    ps: 默认安装在/usr/local/bin目录
    image.png
    f.启动
    /usr/local/bin/redis-server /usr/local/redis-6.2.1/redis.conf
    image.png

    2.2 Docker-Compose安装Redis

    1. version: '3.1'
    2. services:
    3. redis:
    4. image: daocloud.io/library/redis:5.0.7
    5. restart: always
    6. container_name: redis
    7. environment:
    8. - TZ=Asia/Shanghai
    9. ports:
    10. - 6379:6379

    2.3 Docker命令安装Redis

    1.创建映射文件夹实现配置文件
    mkdir -p /docker/redis/redis6379
    上传(拷贝)redis.conf配置文件
    #链接在 2.4Redis的配置文件
    内部修改:
    1.注释掉 #bind 127.0.0.1
    2.设置密码 requirepass lyjava
    2.创建并运行容器
    docker run -d —name redis6379 -p 6379:6379 -v /docker/redis/redis6379/redis.conf:/etc/redis/redis.conf redis:6.2.1 redis-server /etc/redis/redis.conf
    3.开放端口号 6379
    安全组-开放6379(云服务端)
    4.测试
    docker ps
    docker exec -it redis6379 bash
    redis-cli
    输入密码:auth lyjava

    2.4 Redis的配置文件

    redis.conf
    redis.conf.txt
配置项名称 配置项值范围 说明
daemonize yes、no yes表示启用守护进程,默认是no即不以守护进程方式运行。其中Windows系统下不支持启用守护进程方式运行
port 指定 Redis 监听端口,默认端口为 6379
bind 绑定的主机地址,如果需要设置远程访问则直接将这个属性备注下或者改为bind * 即可,这个属性和下面的protected-mode控制了是否可以远程访问 。
protected-mode yes 、no 默认是yes,即开启。设置外部网络连接redis服务,设置方式如下:
1、关闭protected-mode模式,此时外部网络可以直接访问
2、开启protected-mode保护模式,需配置bind ip或者设置访问密码
timeout 300 当客户端闲置多长时间后关闭连接,如果指定为 0,表示关闭该功能
loglevel debug、verbose、notice、warning 日志级别,默认为 notice
databases 16 设置数据库的数量,默认的数据库是0。整个通过客户端工具可以看得到
rdbcompression yes、no 指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大。
dbfilename dump.rdb 指定本地数据库文件名,默认值为 dump.rdb
dir 指定本地数据库存放目录
requirepass 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH 命令提供密码,默认关闭
maxclients 0 设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息。
maxmemory XXX 指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新的 vm 机制,会把 Key 存放内存,Value 会存放在 swap 区。配置项值范围列里XXX为数值。

如果我们想在项目中使用Redis,至少需要配置如下几个信息:
1.bind 外网访问
2.requirepass 设置密码
3.daemonize yes 设置后台启动

2.5客户端连接

自带的redis-cli连接Redis
/usr/local/bin/redis-cli
auth 密码
Redis(NO-Sql) - 图10
也可以使用可视化工具连接Redis
image.png
ps:记得关闭防火墙或者放行6379端口号,要是云服务器就是安全组开放6379端口

4.核心

Redis是K-V的内存存储 键值对

4.0 数据类型

常用的5种数据结构:

  • key-string:一个key对应一个值。
  • key-hash:一个key对应一个Map。
  • key-list:一个key对应一个List列表。
  • key-set:一个key对应一个Set集合。
  • key-zset:一个key对应一个有序的Set集合。等价于:Map

另外3种数据结构:

  • HyperLogLog:计算近似值的。
  • GEO:地理位置。
  • BIT:一般存储的也是一个字符串,存储的是一个byte[]。

image.png

  • key-string:最常用的,一般用于存储一个值。
  • key-hash:存储一个对象数据的。
  • key-list:使用list结构实现栈和队列结构。
  • key-set:交集,差集和并集的操作。
  • key-zset:排行榜,积分存储等操作。

Redis命令:http://doc.redisfans.com/

4.1 String类型常用命令

特点:Key-String 值为String类型

  1. #1. 添加值
  2. set key value 设置内容 如果key存在就是修改,key不存在就是新增
  3. #2. 取值
  4. get key 获取指定key的内容,如果key不存在返回null
  5. #3. 批量操作
  6. mset key value [key value...] 一次性设置多个值
  7. mget key [key...] 一次性获取多个值
  8. #4. 自增命令(自增1)
  9. incr key
  10. #5. 自减命令(自减1)
  11. decr key
  12. #6. 自增或自减指定数量
  13. incrby key increment
  14. decrby key increment
  15. #7. 设置值的同时,指定有效期(每次向Redis中添加数据时,尽量都设置上生存时间)
  16. setex key second value
  17. #8. 设置key的值,如果key存在,不做任何操作,同时返回0,如果key不存在,新增,同时返回1
  18. setnx key value
  19. #9. 在key对应的value后,追加内容
  20. append key value
  21. #10. 查看value字符串的长度
  22. strlen key

4.2 Hash类型常用命令

特点:Key-Hash 值为Hash集合 就是Map

  1. #1. 存储数据
  2. hset key field value 新增元素,如果field存在,就是修改,如果不存在就是新增
  3. #2. 获取数据
  4. hget key field
  5. #3. 批量操作
  6. hmset key field value [field value ...]
  7. hmget key field [field ...]
  8. #4. 自增(指定自增的值)
  9. hincrby key field increment
  10. #5. 设置值(如果key-field不存在,那么就正常添加,如果存在,什么事都不做)
  11. hsetnx key field value
  12. #6. 检查field是否存在
  13. hexists key field
  14. #7. 删除key对应的field,可以删除多个
  15. hdel key field [field ...]
  16. #8. 获取当前hash结构中的全部field和value
  17. hgetall key
  18. #9. 获取当前hash结构中的全部field
  19. hkeys key
  20. #10. 获取当前hash结构中的全部value
  21. hvals key
  22. #11. 获取当前hash结构中field的数量
  23. hlen key

4.3 List类型常用命令

特点:有序,可重复

  1. #1. 存储数据(从左侧插入数据,从右侧插入数据)
  2. lpush key value [value ...]
  3. rpush key value [value ...]
  4. #2. 存储数据(如果key不存在,什么事都不做,如果key存在,但是不是list结构,什么都不做)
  5. lpushx key value
  6. rpushx key value
  7. #3. 修改数据(在存储数据时,指定好你的索引位置,覆盖之前索引位置的数据,
  8. #index超出整个列表的长度,也会失败)
  9. lset key index value
  10. #4. 弹栈方式获取数据(左侧弹出数据,从右侧弹出数据)
  11. lpop key
  12. rpop key
  13. #5. 获取指定索引范围的数据(start从0开始,stop输入-1,代表最后一个,-2代表倒数第二个)
  14. lrange key start stop
  15. #6. 获取指定索引位置的数据
  16. lindex key index
  17. #7. 获取整个列表的长度
  18. llen key
  19. #8. 删除列表中的数据(他是删除当前列表中的count个value值,count > 0从左侧向右侧删除,
  20. #count < 0从右侧向左侧删除,count == 0删除列表中全部的value)
  21. lrem key count value
  22. #9. 保留列表中的数据(保留你指定索引范围内的数据,超过整个索引范围被移除掉)
  23. ltrim key start stop
  24. #10. 将一个列表中最后的一个数据,插入到另外一个列表的头部位置
  25. rpoplpush list1 list2

模拟栈的数据结构:先进后出
lpush+lpop
rpush+rpop
模拟队列的数据结构:先进先出
lpush+rpop
rpush+lpop

4.4 Set类型常用命令

特点:无序、不可重复

  1. #1. 存储数据
  2. sadd key member [member ...]
  3. #2. 获取数据(获取全部数据)
  4. smembers key
  5. #3. 随机获取一个数据(获取的同时,移除数据,count默认为1,代表弹出数据的数量)
  6. spop key [count]
  7. #4. 交集(取多个set集合交集)
  8. sinter set1 set2 ...
  9. #5. 并集(获取全部集合中的数据)
  10. sunion set1 set2 ...
  11. #6. 差集(获取多个集合中不一样的数据)
  12. sdiff set1 set2 ...
  13. # 7. 删除数据
  14. srem key member [member ...]
  15. # 8. 查看当前的set集合中是否包含这个值
  16. sismember key member

4.5 Zset类型常用命令

特点:元素唯一,无序,但是可以Score进行排序, Score:分数、double类型、可以重复 等价于:Map

  1. #1. 添加数据(score必须是数值。member不允许重复的。)
  2. zadd key score member [score member ...]
  3. #2. 修改member的分数(如果member是存在于key中的,正常增加分数,
  4. #如果memeber不存在,这个命令就相当于zadd)
  5. zincrby key increment member
  6. #3. 查看指定的member的分数
  7. zscore key member
  8. #4. 获取zset中数据的数量
  9. zcard key
  10. #5. 根据score的范围查询member数量
  11. zcount key min max
  12. #6. 删除zset中的成员
  13. zrem key member [member...]
  14. #7. 根据分数从小到大排序,获取指定范围内的数据
  15. #(withscores如果添加这个参数,那么会返回member对应的分数)
  16. zrange key start stop [withscores]
  17. #8. 根据分数从大到小排序,获取指定范围内的数据
  18. #(withscores如果添加这个参数,那么会返回member对应的分数)
  19. zrevrange key start stop [withscores]
  20. #9. 根据分数的返回去获取member(withscores代表同时返回score,添加limit,就和MySQL中一样,
  21. #如果不希望等于min或者max的值被查询出来可以采用 ‘(分数’ 相当于 < 但是不等于的方式,
  22. #最大值和最小值使用+inf和-inf来标识)
  23. zrangebyscore key min max [withscores] [limit offset count]
  24. #10. 根据分数的返回去获取member(withscores代表同时返回score,添加limit,就和MySQL中一样)
  25. zrangebyscore key max min [withscores] [limit offset count]

4.6 Geo类型常用命令

特点:地理位置坐标(经纬度)
经度:longitude 纵向
纬度:latitude 横向

  1. #1.经度 纬度 val 新增坐标点
  2. geoadd key
  3. #2.获取指定元素的经纬度
  4. geopos key val
  5. #3.获取val1到val2的直线距离单位米
  6. geodist key val1 val2
  7. #4.经度 纬度 半径数据 单位(m km) 获取指定点的指定半径内的元素
  8. georadius key

4.7 Bitmap类型常用命令

特点:Key-Bitmap位 0或1的存储 值只能是0或者1

  1. #1.索引 值 新增内容
  2. setbit key
  3. #2.索引 获取指定索引的值
  4. getbit key
  5. #3.获取值为1的数量
  6. bitcount key

Redis中Key的常用命令

  1. #1. 查看Redis中的全部的key(pattern:* ,xxx*,*xxx)
  2. keys pattern
  3. #2. 查看某一个key是否存在(1 - key存在,0 - key不存在)
  4. exists key
  5. #3. 删除key
  6. del key [key ...]
  7. #4. 设置key的生存时间,单位为秒,单位为毫秒,设置还能活多久
  8. expire key second
  9. pexpire key milliseconds
  10. #5. 设置key的生存时间,单位为秒,单位为毫秒,设置能活到什么时间点
  11. expireat key timestamp
  12. pexpireat key milliseconds
  13. #6. 查看key的剩余生存时间,单位为秒,单位为毫秒
  14. #(-2 - 当前key不存在,-1 - 当前key没有设置生存时间,具体剩余的生存时间)
  15. ttl key
  16. pttl key
  17. #7. 移除key的生存时间(1 - 移除成功,0 - key不存在生存时间,key不存在)
  18. persist key
  19. #8. 选择操作的库
  20. select 0~15
  21. #9. 移动key到另外一个库中
  22. move key db

Redis中系统常用命令

  1. #1. 清空当前所在的数据库
  2. flushdb
  3. #2. 清空全部数据库
  4. flushall
  5. #3. 查看当前数据库中有多少个key
  6. dbsize
  7. #4. 查看最后一次操作的时间
  8. lastsave
  9. #5. 实时监控Redis服务接收到的命令
  10. monitor
  11. del key 删除指定的key
  12. ttl key 查看key的剩余有效期
  13. keys * 匹配所有的key (开发中禁用)
  14. scan 游标 match * count 数量 匹配所有的key,返回指定的数量
  15. expire key seconds 设置key的有效期
  16. flushdb 清空当前所在的数据库
  17. flushall 清空全部数据库
  18. dbsize 查看当前数据库中有多少个key
  19. lastsave 查看最后一次操作的时间
  20. monitor 实时监控Redis服务接收到的命令
  21. exists key 验证key是否存在,存在返回1,不存在返回0
  22. persist key 移除有效期,永久有效
  23. auth 密码 密码认证

5.操作

5.1 Jedis

a.依赖jar

  1. <dependency>
  2. <groupId>redis.clients</groupId>
  3. <artifactId>jedis</artifactId>
  4. <version>2.9.0</version>
  5. </dependency>

b.编写代码

  1. //1. 连接Redis
  2. Jedis jedis = new Jedis("192.168.199.109",6379);
  3. //2. 操作Redis - 因为Redis的命令是什么,Jedis的方法就是什么
  4. jedis.set("name","李四");
  5. String value = jedis.get("name");
  6. System.out.println(value);
  7. //3. 释放资源
  8. jedis.close();

c.其他复杂操作

  1. //1. 连接Redis服务
  2. Jedis jedis = new Jedis("192.168.199.109",6379);
  3. //------------------------------------------------
  4. //2.1 准备key(String)-value(User)
  5. String key = "user";
  6. User value = new User(1,"张三",new Date());
  7. //2.2 将key和value转换为byte[]
  8. byte[] byteKey = SerializationUtils.serialize(key);
  9. byte[] byteValue = SerializationUtils.serialize(value);
  10. //2.3 将key和value存储到Redis
  11. jedis.set(byteKey,byteValue);
  12. //2.2 将key转换为byte[]
  13. byte[] byteKey1 = SerializationUtils.serialize(key);
  14. // jedis去Redis中获取value
  15. byte[] value1 = jedis.get(byteKey1);
  16. // 将value反序列化为User对象
  17. User user = (User) SerializationUtils.deserialize(value);
  18. String stringKey = "stringUser";
  19. User value = new User(2,"李四",new Date());
  20. //2.2 使用fastJSON将value转化为json字符串
  21. String stringValue = JSON.toJSONString(value);
  22. //存储到Redis中
  23. jedis.set(stringKey,stringValue);
  24. String value2 = jedis.get(key);
  25. // 将value反序列化为User
  26. User user2 = JSON.parseObject(value2, User.class);
  27. //输出
  28. System.out.println("user:" + user2);
  29. //------------------------------------------------
  30. //3. 释放资源
  31. jedis.close();

d.连接池的使用

  1. //1. 创建连接池配置信息
  2. GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
  3. poolConfig.setMaxTotal(100); // 连接池中最大的活跃数
  4. poolConfig.setMaxIdle(10); // 最大空闲数
  5. poolConfig.setMinIdle(5); // 最小空闲数
  6. poolConfig.setMaxWaitMillis(3000); // 当连接池空了之后,多久没获取到Jedis对象,就超时
  7. //2. 创建连接池
  8. JedisPool pool = new JedisPool(poolConfig,"192.168.199.109",6379);
  9. //3. 通过连接池获取jedis对象
  10. Jedis jedis = pool.getResource();
  11. //4. 操作
  12. String value = jedis.get("stringUser");
  13. System.out.println("user:" + value);
  14. //5. 释放资源
  15. jedis.close();

6.进阶

6.1 事务

Redis的事务:一次事务操作,改成功的成功,该失败的失败。
先开启事务,执行一些列的命令,但是命令不会立即执行,会被放在一个队列中,如果你执行事务,那么这个队列中的命令全部执行,如果取消了事务,一个队列中的命令全部作废。
- 开启事务:multi
- 输入要执行的命令:被放入到一个队列中
- 执行事务:exec
- 取消事务:discard
Redis的事务想发挥功能,需要配置watch监听机制
在开启事务之前,先通过watch命令去监听一个或多个key,在开启事务之后,如果有其他客户端修改了我监听的key,事务会自动取消。
如果执行了事务,或者取消了事务,watch监听自动消除,一般不需要手动执行unwatch。

事务详解

Redis中事务的使用其实非常简单,通过MULTI命令即可。
image.png
在MULTI命令执行之后,我们可以继续发送命令执行,但此时命令不会立即执行,而是保持到一个队列中,如下
image.png
当所有的命令都输入完成后,我们可以输入EXEC命令来执行队列中的命令,如下
image.png

事务异常

事务中的异常有两种情况:
1、进入队列之前发生错误
比较常见的命令错误,此类异常redis的处理方式是,服务器会对进入队列失败的情况进行记录,在执行exec命令提交的时候,对于该命令不会执行并放弃这个事务,如下:
image.png
注意!!! redis事务中有一个异常并不会造成其他命令的回滚!
2、执行exec命令后发生的异常
对于这种情况,redis中也不会做特别的处理。事务中的命令继续执行
image.png
不同于关系型数据库,redis中没有回滚操作,官方解释是:
Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速;

Watch(监控机制)

watch命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到exec命令(事务中的命令是在exec之后才执行的,所以在multi命令后可以修改watch监控的键值)。假设我们通过watch命令在事务执行之前监控了多个Keys,倘若在watch之后有任何Key的值发生了变化,exec命令执行的事务都将被放弃,同时返回Null multi-bulk应答以通知调用者事务执行失败。
image.png
exec后会自动执行unwatch命令,撤销监控

Unwatch(撤销watch)

撤销对一个key的监控
image.png

6.2 持久化

Redis提供2种方式实现持久化:1.RDB 2.AOF
同时开启RDB和AOF的注意事项:
如果同时开启了AOF和RDB持久化,那么在Redis宕机(死机)重启之后,需要加载一个持久化文件,优先选择AOF文件。
如果先开启了RDB,再次开启AOF,如果RDB执行了持久化,那么RDB文件中的内容会被AOF覆盖掉。
RDB
RDB是Redis默认的持久化机制
RDB持久化文件,速度比较快,而且存储的是一个二进制的文件,传输起来很方便。
RDB持久化的时机:
save 900 1:在900秒内,有1个key改变了,就执行RDB持久化。
save 300 10:在300秒内,有10个key改变了,就执行RDB持久化。
save 60 10000:在60秒内,有10000个key改变了,就执行RDB持久化。
RDB无法保证数据的绝对安全。
RDB存储的是数据,时间间隔无法实时持久化
AOF
AOF持久化机制默认是关闭的,Redis官方推荐同时开启RDB和AOF持久化,更安全,避免数据丢失。
AOF持久化的速度,相对RDB较慢的,存储的是一个文本文件,到了后期文件会比较大,传输困难。
AOF持久化时机。
appendfsync always:每执行一个写操作,立即持久化到AOF文件中,性能比较低。
appendfsync everysec:每秒执行一次持久化。
appendfsync no:会根据你的操作系统不同,环境的不同,在一定时间内执行一次持久化。
AOF相对RDB更安全,推荐同时开启AOF和RDB。
AOF存储的是命令(更改数据的命令),可以实时持久化

6.3 过期策略

key的生存时间到了,Redis会立即删除吗?不会立即删除。
有以下几种策略:
- 定期删除:Redis每隔一段时间就去会去查看Redis设置了过期时间的key,会再100ms的间隔中默认查看3个key。
- 惰性删除:如果当你去查询一个已经过了生存时间的key时,Redis会先查看当前key的生存时间,是否已经到了,直接删除当前key,并且给用户返回一个空值。

6.4淘汰机制

在Redis内存已经满的时候,添加了一个新的数据,执行淘汰机制(防止Redis服务器内存溢出)。
volatile-lru:在内存不足时,Redis会在设置过了生存时间的key中干掉一个最近最少使用的key。
allkeys-lru:在内存不足时,Redis会在全部的key中干掉一个最近最少使用的key。
volatile-lfu:在内存不足时,Redis会在设置过了生存时间的key中干掉一个最近最少频次使用的key。
allkeys-lfu:在内存不足时,Redis会再全部的key中干掉一个最近最少频次使用的key。
volatile-random:在内存不足时,Redis会再设置过了生存时间的key中随机干掉一个。
allkeys-random:在内存不足时,Redis会再全部的key中随机干掉一个。
volatile-ttl:在内存不足时,Redis会在设置过了生存时间的key中干掉一个剩余生存时间最少的key。
noeviction:(默认)在内存不足时,直接报错。
指定淘汰机制的方式:maxmemory-policy 具体策略,
设置Redis的最大内存:maxmemory 字节大小

6.5主从复制

单机版 Redis存在读写瓶颈的问题
(保证每一台服务器的数据都一致)
image.png

  1. version: "3.1"
  2. services:
  3. redis1:
  4. image: daocloud.io/library/redis:5.0.7
  5. restart: always
  6. container_name: redis1
  7. environment:
  8. - TZ=Asia/Shanghai
  9. ports:
  10. - 7001:6379
  11. volumes:
  12. - ./conf/redis1.conf:/usr/local/redis/redis.conf
  13. command: ["redis-server","/usr/local/redis/redis.conf"]
  14. redis2:
  15. image: daocloud.io/library/redis:5.0.7
  16. restart: always
  17. container_name: redis2
  18. environment:
  19. - TZ=Asia/Shanghai
  20. ports:
  21. - 7002:6379
  22. volumes:
  23. - ./conf/redis2.conf:/usr/local/redis/redis.conf
  24. links:
  25. - redis1:master
  26. command: ["redis-server","/usr/local/redis/redis.conf"]
  27. redis3:
  28. image: daocloud.io/library/redis:5.0.7
  29. restart: always
  30. container_name: redis3
  31. environment:
  32. - TZ=Asia/Shanghai
  33. ports:
  34. - 7003:6379
  35. volumes:
  36. - ./conf/redis3.conf:/usr/local/redis/redis.conf
  37. links:
  38. - redis1:master
  39. command: ["redis-server","/usr/local/redis/redis.conf"]

6.6Redis哨兵

哨兵可以帮助我们解决主从架构中的单点故障问题
(监控主库的运行,如果主库宕机,在从库中选择一个作为主库)
image.png
修改了以下docker-compose.yml,为了可以在容器内部使用哨兵的配置:

  1. version: "3.1"
  2. services:
  3. redis1:
  4. image: daocloud.io/library/redis:5.0.7
  5. restart: always
  6. container_name: redis1
  7. environment:
  8. - TZ=Asia/Shanghai
  9. ports:
  10. - 7001:6379
  11. volumes:
  12. - ./conf/redis1.conf:/usr/local/redis/redis.conf
  13. - ./conf/sentinel1.conf:/data/sentinel.conf # 添加的内容
  14. command: ["redis-server","/usr/local/redis/redis.conf"]
  15. redis2:
  16. image: daocloud.io/library/redis:5.0.7
  17. restart: always
  18. container_name: redis2
  19. environment:
  20. - TZ=Asia/Shanghai
  21. ports:
  22. - 7002:6379
  23. volumes:
  24. - ./conf/redis2.conf:/usr/local/redis/redis.conf
  25. - ./conf/sentinel2.conf:/data/sentinel.conf # 添加的内容
  26. links:
  27. - redis1:master
  28. command: ["redis-server","/usr/local/redis/redis.conf"]
  29. redis3:
  30. image: daocloud.io/library/redis:5.0.7
  31. restart: always
  32. container_name: redis3
  33. environment:
  34. - TZ=Asia/Shanghai
  35. ports:
  36. - 7003:6379
  37. volumes:
  38. - ./conf/redis3.conf:/usr/local/redis/redis.conf
  39. - ./conf/sentinel3.conf:/data/sentinel.conf # 添加的内容
  40. links:
  41. - redis1:master
  42. command: ["redis-server","/usr/local/redis/redis.conf"]

准备哨兵的配置文件,并且在容器内部手动启动哨兵即可:

  1. # 哨兵需要后台启动
  2. daemonize yes
  3. # 指定Master节点的ip和端口(主)
  4. sentinel monitor master localhost 6379 2
  5. # 指定Master节点的ip和端口(从)
  6. sentinel monitor master master 6379 2
  7. # 哨兵每隔多久监听一次redis架构
  8. sentinel down-after-milliseconds mymaster 10000