前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >缓存之Redis了解及使用

缓存之Redis了解及使用

作者头像
sucl
发布2019-08-07 15:23:40
5080
发布2019-08-07 15:23:40
举报
文章被收录于专栏:企业平台构建
  • 介绍

redis是一种支持Key-Value等多种数据结构的存储系统。可用于缓存,事件发布或订阅,高速队列等场景。该数据库使用ANSI C语言编写,支持网络,提供字符串,哈希,列表,队列,集合结构直接存取,基于内存,可持久化。

  • 安装

由于开发机器一般都是windows,但是redis一般都是支持linux,可以看到最新的redis都到5.x了,当然redis也开发了windows版本,只不过版本停留在3.x,可以到github上下载,地址,解压之后如下:

只需要双击redis-server.exe即可启动:

当然如果想在windows上使用最新版本的redis,我们可以使用docker容器去启动。

  • 说明

提到redis我们一般都会知道这是一个nosql的数据库,主要作为缓存使用,主要源于其高速的读写速度,在业务与关系型数据库间,通过构建一层缓存访问,可以减少与系统io间的通信,从而降低系统资源的损耗。

  1. 优点
代码语言:javascript
复制
    1 读写速度快
    2 支持AOF和RDB两种持久化方式
    3 支持主从复制
    4 支持string、hash、list、set、sorted set五种数据类型
    5 支持事务、过期、发布订阅、多DB等策略
  1. 缺点
代码语言:javascript
复制
    1 Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
    2 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
    3 redis的主从复制采用全量复制,复制过程中主机会fork出一个子进程对内存做一份快照,并将子进程的内存快照保存为文件发送给从机,这一过程需要确保主机有足够多的空余内存。若快照文件较大,对集群的服务能力会产生较大的影响,而且复制过程是在从机新加入集群或者从机和主机网络断开重连时都会进行,也就是网络波动都会造成主机和从机间的一次全量的数据复制,这对实际的系统运营造成了不小的麻烦。
    4 Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费
    5 由于是基于内存的数据库,存储的数据量与单台机器的内存有关
    6 单线程机制导致对cpu的使用效率降低
    7 重启或故障后,对数据的加载与恢复,存在数据丢失与耗时,导致服务的不够可靠
  1. 使用场景(来源https://www.cnblogs.com/dukuan/p/9132600.html
代码语言:javascript
复制
1、字符串使用场景
    a) 缓存功能
        典型使用场景:Redis作为缓存层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取,由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用。
        开发提示:与MySQL等关系型数据库不同的是,Redis没有命令空间,而且也没有对键名有强制要求,但设计合理的键名,有利于防止键冲突和项目的可维护性,比较推荐的方式是使用“业务名:对象名:id:[属性]”作为键名。例如MySQL的数据库名为vs,用户表名为user,那么对应的键可以用"vs:user:1","vs:user:1:name"来表示,如果当前Redis只被一个业务使用,甚至可以去掉vs。如果键名比较长,例如"user:{uid}:friends:message:{mid}",可以在能描述含义的前提下适当减少键的长度,例如采用缩写形式,从而减少由于键过长的内存浪费。
    b) 计数
        典型应用场景:视频播放数计数的基础组件,用户每播放一次视频,相应的视频播放数就会自增1。Redis可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。
        开发提示:实际上一个真实的计数系统要考虑的问题会很多,防作弊、按照不同维度计数,数据持久化到底层数据源等。

    c) 共享Session
        典型应用场景:用户登陆信息,Redis将用户的Session进行集中管理,每次用户更新或查询登陆信息都直接从Redis中集中获取。
    d) 限速
        典型应用场景:验证码接口访问频率限制,用户登陆时需要让用户输入手机验证码,从而确定是否是用户本人,但是为了短信接口不被频繁访问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过5次。

2、哈希使用场景
    a) 缓存用户信息
        相比于使用字符串序列化缓存用户信息,哈希类型变得更加直观,并且在更新操作上会更加便捷。可以将每个用户的id定义为键后缀,多对field-value对应每个用户的属性。
        哈希类型和关系型数据库不同之处:
              哈希类型是稀疏的,而关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的field,而关系型数据库一旦添加新的列,所有行都要为其设置值(即使为NULL)。
              关系型数据库可以做复杂的关系查询,而Redis去模拟关系型复杂查询开发困难,维护成本高。
        三种缓存用户信息优缺点比较:
              原生字符串类型:每个属性一个键
                   优点:简单直观,每个属性都支持更新操作。
                   缺点:占用过多的键,内存占用量较大,同时用户信息内聚性比较差,所以此种方案一般不会在生产环境使用。
             序列化字符串类型:将用户信息序列化后用一个键保存。
                  优点:简化编程,如果合理的使用序列化可以提高内存的使用效率。
                  缺点:序列化和反序列化有一定的开销,同时每次更新属性都需要把全部数据取出进行反序列化,更新后再序列化到Redis中。
             哈希类型:每个用户属性使用一对field-value,但是只用一个键保存。
                  优点:简单直观,如果使用合理可以减少内存空间的使用。
                  缺点:要控制哈希在ziplist和hashtable两种内部编码的转换,hashtable会消耗更多内存。

3、列表使用场景
    a) 消息队列
        Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的"抢"列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。
    b) 文章列表
        每个用户有属于自己的文章列表,现在需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素。
    c) 开发提示
        lpush + lpop = Stack(栈)
        lpush + rpop = Queue(队列)
        lpush + ltrim = Capped Collection(有限集合)
        lpush + brpop = Message Queue(消息队列)

4、集合
    a) 标签(tag)
        集合类型比较典型的使用场景是标签(tag),例如一个用户可能对娱乐、体育比较感兴趣,另一个用户可能对历史、新闻比较感兴趣,这些兴趣就是标签。 开发提示:用户和标签的关系维护应该在一个事物执行,防止部分命令失败造成的数据不一致。

5、有序集合
    a) 排行榜系统
        有序集合比较典型的使用场景就是排行榜系统,例如视频网站需要对用户上传的视频做排行榜,榜单的维度可能是多个方面的:按照时间、按照播放数量、按照获得的赞数。
  • 使用

继续上面的,使用redis可以直接使用期安装包中提供的工具以命令的方式进行操作,当然一般我们将redis作为缓存中间件,会配合其他编程语言在特定下的环境使用,当然 在此主要是学习,我们可以先以命令的方式对redis有基本的了解。

双击redis-cli.exe,进入操作界面:

然后可以通过redis命令进行操作,常用命令,下面看一些常用的命令来了解redis(来源 https://www.cnblogs.com/cxxjohnson/p/9072383.html):

设置密码:config set requirepass 123456;认证:auth 123456.

代码语言:javascript
复制
1.基于内存的key-value数据库
2.基于c语言编写的,可以支持多种语言的api //set每秒11万次,取get 81000次
3.支持数据持久化
4.value可以是string,hash, list, set, sorted set

使用场景
1. 去最新n个数据的操作
2. 排行榜,取top n个数据 //最佳人气前10条
3. 精确的设置过期时间
4. 计数器
5. 实时系统, 反垃圾系统
6. pub, sub发布订阅构建实时消息系统
7. 构建消息队列
8. 缓存

cmd访问redis
redis-cli.exe -h 127.0.0.1 -p 6379


key
    keys * 获取所有的key
    select 0 选择第一个库
    move myString 1 将当前的数据库key移动到某个数据库,目标库有,则不能移动
    flush db      清除指定库
    randomkey     随机key
    type key      类型
    
    set key1 value1 设置key
    get key1    获取key
    mset key1 value1 key2 value2 key3 value3
    mget key1 key2 key3
    del key1   删除key
    exists key      判断是否存在key
    expire key 10   10过期
    pexpire key 1000 毫秒
    persist key     删除过期时间

string
    set name cxx
    get name
    getrange name 0 -1        字符串分段
    getset name new_cxx       设置值,返回旧值
    mset key1 key2            批量设置
    mget key1 key2            批量获取
    setnx key value           不存在就插入(not exists)
    setex key time value      过期时间(expire)
    setrange key index value  从index开始替换value
    incr age        递增
    incrby age 10   递增
    decr age        递减
    decrby age 10   递减
    incrbyfloat     增减浮点数
    append          追加
    strlen          长度
    getbit/setbit/bitcount/bitop    位操作
    
hash
    hset myhash name cxx
    hget myhash name
    hmset myhash name cxx age 25 note "i am notes"
    hmget myhash name age note   
    hgetall myhash               获取所有的
    hexists myhash name          是否存在
    hsetnx myhash score 100      设置不存在的
    hincrby myhash id 1          递增
    hdel myhash name             删除
    hkeys myhash                 只取key
    hvals myhash                 只取value
    hlen myhash                  长度

list
    lpush mylist a b c  左插入
    rpush mylist x y z  右插入
    lrange mylist 0 -1  数据集合
    lpop mylist  弹出元素
    rpop mylist  弹出元素
    llen mylist  长度
    lrem mylist count value  删除
    lindex mylist 2          指定索引的值
    lset mylist 2 n          索引设值
    ltrim mylist 0 4         删除key
    linsert mylist before a  插入
    linsert mylist after a   插入
    rpoplpush list list2     转移列表的数据
    
set
    sadd myset redis 
    smembers myset       数据集合
    srem myset set1         删除
    sismember myset set1 判断元素是否在集合中
    scard key_name       个数
    sdiff | sinter | sunion 操作:集合间运算:差集 | 交集 | 并集
    srandmember          随机获取集合中的元素
    spop                 从集合中弹出一个元素
    
zset
    zadd zset 1 one
    zadd zset 2 two
    zadd zset 3 three
    zincrby zset 1 one              增长分数
    zscore zset two                 获取分数
    zrange zset 0 -1 withscores     范围值
    zrangebyscore zset 10 25 withscores 指定范围的值
    zrangebyscore zset 10 25 withscores limit 1 2 分页
    Zrevrangebyscore zset 10 25 withscores  指定范围的值
    zcard zset  元素数量
    Zcount zset 获得指定分数范围内的元素个数
    Zrem zset one two        删除一个或多个元素
    Zremrangebyrank zset 0 1  按照排名范围删除元素
    Zremrangebyscore zset 0 1 按照分数范围删除元素
    Zrank zset 0 -1    分数最小的元素排名为0
    Zrevrank zset 0 -1  分数最大的元素排名为0
    Zinterstore
    zunionstore rank:last_week 7 rank:20150323 rank:20150324 rank:20150325  weights 1 1 1 1 1 1 1
    
    
排序:
    sort mylist  排序
    sort mylist alpha desc limit 0 2 字母排序
    sort list by it:* desc           by命令
    sort list by it:* desc get it:*  get参数
    sort list by it:* desc get it:* store sorc:result  sort命令之store参数:表示把sort查询的结果集保存起来

订阅与发布:
    订阅频道:subscribe chat1
    发布消息:publish chat1 "hell0 ni hao"
    查看频道:pubsub channels
    查看某个频道的订阅者数量: pubsub numsub chat1
    退订指定频道: unsubscrible chat1   , punsubscribe java.*
    订阅一组频道: psubscribe java.*
    
redis事物:
     隔离性,原子性, 
     步骤:  开始事务,执行命令,提交事务
             multi  //开启事务
             sadd myset a b c
             sadd myset e f g
             lpush mylist aa bb cc
             lpush mylist dd ff gg

服务器管理
    dump.rdb
    appendonly.aof
    //BgRewriteAof 异步执行一个aop(appendOnly file)文件重写
    会创建当前一个AOF文件体积的优化版本
    
    //BgSave 后台异步保存数据到磁盘,会在当前目录下创建文件dump.rdb
    //save同步保存数据到磁盘,会阻塞主进程,别的客户端无法连接
    
    //client kill 关闭客户端连接
    //client list 列出所有的客户端
    
    //给客户端设置一个名称
      client setname myclient1
      client getname
      
     config get port
     //configRewrite 对redis的配置文件进行改写


rdb 
save 900 1
save 300 10
save 60 10000

aop备份处理
appendonly yes    开启持久化
appendfsync everysec  每秒备份一次

命令:
bgsave异步保存数据到磁盘(快照保存)
lastsave返回上次成功保存到磁盘的unix的时间戳
shutdown同步保存到服务器并关闭redis服务器
bgrewriteaof文件压缩处理(命令)

redis的使用在各个语言中都有相关的api提供,作为客户端与其服务器之间进行数据交换与通信,打开官网可以看到:

那么今天我们则使用java如何与redis协助,从而调用其内在的api实现数据的存取。

首先我们需要引入相关的依赖:

代码语言:javascript
复制
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

简单的基本的用法如下:

代码语言:javascript
复制
public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost",6379);
        jedis.auth("123456");
        System.out.println("连接成功:"+jedis);
//        System.out.println(jedis.isConnected());
        jedis.connect();

//        stringTest(jedis);
//        hashTest(jedis);
//        listTest(jedis);
//        setTest(jedis);
        sortedSetTest(jedis);
    }

    public static void stringTest(Jedis jedis){
        jedis.set("s1","hello");//存值
        System.out.println(jedis.get("s1"));//取值
        System.out.println(jedis.type("s1"));//key对应值的类型
        System.out.println(jedis.keys("*"));//查看所有key
        jedis.rename("s1","s11");//重命名key
        System.out.println(jedis.keys("*"));
        System.out.println(jedis.get("s11"));
        jedis.del("s11");//删除key
        System.out.println(jedis.keys("*"));
    }

    /**
     * k-v
     * @param jedis
     */
    public static void hashTest(Jedis jedis){
        jedis.hset("h1","hk1","hv1");
        jedis.hset("h1","hk1","hv2");//将上面的替换了
        System.out.println("keys : " +jedis.keys("*"));
        System.out.println(jedis.hget("h1","hk1"));
        jedis.hdel("h1","hk1");//删除,只有一个域,删除了则key也没了
//        jedis.del("h1");
        System.out.println("keys : " +jedis.keys("*"));

        Map<String, String> hash = new HashMap<>();
        hash.put("field1","v1");
        hash.put("field2","v2");
        jedis.hmset("h2",hash);
        System.out.println(jedis.hget("h2","field1"));
        System.out.println(jedis.hmget("h2","field1","field1"));
        jedis.hdel("h2","field1");
        System.out.println(jedis.hgetAll("h2"));
        jedis.del("h2");

        //是否存在
        jedis.hexists("key1", "field1");
        //返回哈希表key中的所有域
        jedis.hkeys("key1");
        //返回哈希表key中的所有值
        jedis.hvals("key1");
    }
    /**
    * 双向链表,FIFO
    */
    public static void listTest(Jedis jedis){
        //排序v4 v3 v 2 v1
        jedis.lpush("l1","v1","v2","v3","v4");//往列表头插入,因此v4在第一个
        System.out.println(jedis.lindex("l1",0));
        System.out.println(jedis.lpop("l1"));//取出并删除第一个
        System.out.println(jedis.lrange("l1",1,5));//取值,如果超出范围值,则循环
        Long linsert = jedis.linsert("l1", BinaryClient.LIST_POSITION.BEFORE, "v2", "v99");
        //保证list只有最新的N条数据
        //jedis.ltrim("login:last_login_times", 0, N-1)
        System.out.println(jedis.lrange("l1",0,-1));

        jedis.del("l1");
    }

    public static void setTest(Jedis jedis){
        jedis.sadd("s1", "value0");
        jedis.sadd("s1", "value1");//和上面的hash不同,set存储的的是k-vs
        System.out.println(jedis.smembers("s1"));

        //判断元素是否是集合key的成员
        System.out.println(jedis.sismember("s1", "value2"));

        //返回集合key的元素的数量
        System.out.println(jedis.scard("s1"));

        //返回一个集合的全部成员,该集合是所有给定集合的交集
        System.out.println(jedis.sinter("s1","s2"));

        //返回一个集合的全部成员,该集合是所有给定集合的并集
        System.out.println(jedis.sunion("s1","s2"));

        //返回一个集合的全部成员,该集合是所有给定集合的差集
        System.out.println(jedis.sdiff("s1","s2"));

        jedis.del("s1");
    }

    public static void sortedSetTest(Jedis jedis){
        jedis.zadd("z1",1,"v1");
        jedis.zadd("z1",1,"v2");
        jedis.zadd("z1",2,"v3");
        jedis.zadd("z1",3,"v4");
        jedis.zadd("z1",4,"v5");
        jedis.zadd("z1",5,"v6");
        System.out.println(jedis.zcard("z1"));
        System.out.println(jedis.zcount("z1",2,4));
        System.out.println( jedis.zrange("z1",0,-1));
        //为有序集 key 的成员 member 的 score 值加上增量 increment,如果member不存在,则新增
        System.out.println(jedis.zincrby("z1",1,"v1"));
        System.out.println( jedis.zrange("z1",0,-1));
        //指定区间数量 [* [*([a [b;[1 [2)
        System.out.println(jedis.zlexcount("z1","-", "+"));
        //将两个set的相同值的score相加,生成第三个set,没有的值则不管
        jedis.zadd("z2",5,"v1");
        jedis.zadd("z2",8,"v3");
        jedis.zinterstore("z3","z1","z2");
        System.out.println(jedis.zrange("z3",0,-1));
        jedis.zrem("z1","v1","v2");
        System.out.println(jedis.zrange("z1",0,-1));
//        System.out.println(jedis);

        jedis.del("z1","z2","z3");
    }

    public static void other(Jedis jedis){
        jedis.select(0);//redis一共有16个db,默认为0
        jedis.expire("key1",5);//存活时间
        jedis.ttl("key1");//剩余存活时间
        jedis.setnx("key2","10");//不存在则添加,存在不作处理
        
        //....
    }

redis提供了很多的api,这个 需要不断的熟悉与经常的使用,当然关于redis的原理以及一些特性也是需要去了解的,那样在真正去使用的时候也能够预先处理可能的故障或者能够解释一些奇怪的现象。

作为数据库,一般都会有一些客户化的客户端方便我们操作,可以使用RedisDesktopManager来更直观的操作redis。

1.持久化

代码语言:javascript
复制
持久化分为两种:
RDB(Redis DataBase)
AOF(Append Only File) 

RDB:在指定的时间间隔内,将内存中的数据集快照(snapshot)写入磁盘,它恢复时,是将快照文件直接读到内存里;Redis 会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,在用这个临时文件替换上次持久化好的文件;整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能;如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效;保存为dump.rdb文件;是整个内存压缩过的Snapshot, RDB持久化策略,与快照触发条件一样;
  将备份文件(dump.rdb)移动到redis安装目录并启动服务即可恢复;
 - 优缺点:
    · 优:适合大规模数据恢复,但对数据完整性和一致性要求不高;
    · 缺:系统出现故障后,会导致最后一次快照后修改的数据丢失;fork子进程,由于是拷贝和原来同样的进程,导致系统消耗成原来两倍,从而影响性能。
 - 触发条件:
    · 配置文件中默认的快照配置,冷拷贝以后重新使用(即备份文件和要恢复备份的机器不是同一台); 
    · save或bgsave命令,立刻生成dump.rbd文件;
         save时,只管保存,其他不管,全部阻塞;
         bgsave:Redis 会在后台异步执行快照操作,快照的同时还可以响应客户端请求;可以通过lastsave命令获取最后一次成功执行快照的时间;
    · 执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意义; 

AOF:以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只需追加文件但不可以改写文件, redis启动之初会读取该文件,重新构建数据,换言之,redis重启的话,就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作;redis.conf中的配置appendonly no,即该种持久化方式默认为关闭;redis.conf中的配置appendfsync=everysec,出厂默认值,异步操作,每秒记录,若一秒内宕机,有数据丢失;appendfsync=always: 同步持久化,每次发生数据变更会被立即记录到磁盘,性能较差但数据完整性比较好;
 - 优缺点:
    · 优:同步持久化,appendfsync=always;每修改同步,appendfsync=everysec;
    · 缺:相同数据集的数据而言,aof文件要远大于rdb文件,恢复速度慢于rdb;AOF运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同;

对比:
    1、RDB 持久化方式能够在指定的时间间隔,对数据进行快照存储;
    2、AOF 持久化方式记录每次对服务器写的操作,当服务器重启的时候,会重新执行这些命令来恢复原始的数据,AOF 命令,以redis协议追加保存每次写的操作到文件末尾,Redis 还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大;
    3、同时开启两种持久化方式:在这种情况下,当redis重启的时候,会优先加载AOF文件来恢复原始的数据,因为在通常情况下,AOF文件保存的数据集要比RDB文件保存的数据集完整;

2.事务

代码语言:javascript
复制
原理: 
    事务本质上是一组命令的集合;一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞;执行过程分为三个阶段:开启: 以MULTI开始一个事务;入队: 将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面;执行: 以EXEC命令触发事务;
命令:
    -  MULTI: 标记一个事务块的开始;
    - EXEC: 执行所有事务块内的命令;
    - DISCARD: 取消事务,放弃执行事务块内的所有命令;
    - WATCH: 监控一个(或多个)key,如果在事务执行之前,这个(或这些)key被其他命令所改动,那么事务将被打断;
    - UNWATCH: 取消WATCH命令对所有key的监视;
特性: 
    - 单独的隔离操作:事务中的所有命令都会序列化,按顺序地执行;事务在执行的过程中,不会被其他客户端发送来的命令请求所打断;
    - 没有隔离级别的概念:队列中的命令,在没有提交之前不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在"事务内的查询要看到事务里的更新,在事务外查询不能看到"这个让人万分头痛的问题;
    - 不保证原子性:redis同一个事务中,如果有一条命令执行失败,其他的命令仍然会被执行,没有回滚;

3.发布订阅

代码语言:javascript
复制
Redis 的发布/订阅:进程间的一种信息通信模式,发送者(pub)发送消息,订阅者(sub)接收消息;
命令:
    - SUBSCRIBE [channel] 订阅频道
    - PUBLISH [channel] [message] 发布消息
    - PSUBSCRIBE pattern [pattern ...] 订阅一个或多个符合给定模式的频道
    - PUNSUBSCRIBE [pattern [pattern ...]] 退订所有给定模式的频道
    - PUBSUB subcommand [argument [argument ...]] 查看订阅与发布系统状态

4.主从复制

代码语言:javascript
复制
主从复制: 
    主机数据更新后,根据配置和策略,自动同步到备机的master/slave机制,Master以写为主,Slave以读为主;
作用:
    读写分离;容灾备份
使用:
    1、配从(库)不配主(库);
    2、从库配置: slaveof 主库IP 主库端口
        每次与master断开之后,都需要重新连接,除非配置进redis.conf文件;
        info replication: 查看当前库的状态;
    3、修改配置文件
        拷贝多个 redis.conf 文件;
        设置 daemonize yes, Pid 文件名字, 指定端口, Log文件的名字, Dump.rbd名字;
常用3招
    1、一主二从(一个Master,两个Slave)
    2、薪火相传
            上一个Slave可以是下一个Slave的Master,Slave同样可以接收其他Slaves的连接和同步请求,那么,该Slave就是下一个Slave的Master,这样,可以有效减轻master的写压力;
    中途变更转向:会清除之前的数据,重新建立拷贝最新的; slaveof 新主库IP 新主库端口;
    3、反客为主
        slaveof no one,使当前数据库停止与其他数据库的同步,转成主数据库;
原理:
1、slave 成功连接到master后,会发送一个sync命令;
2、Master 接到命令,启动后台的存盘进程,同时,收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master 将传送整个数据文件到slave,以完成一次完全同步;
    全量复制:slave 服务在接收到数据库文件数据后,将其存盘并加载到内存中;
    增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步;
3、但是,只要是重新连接master,一次完全同步(全量复制)将被自动执行;
    复制的缺点:复制的延时;由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步
4、到slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重;
哨兵模式(Sentinel)
    "反客为主"的自动版,能够后台监控主机是否故障,如果发生故障,根据投票数自动将从库转换为主库;
使用步骤
    配置 sentinel.conf,一个sentinel能同时监控多个Master;

更多参考:

http://redisdoc.com/topic/sentinel.html#id14

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档