Redis个人总结

Redis

一. 认识NoSQL

1.1技术的分类

1、解决功能性的问题:Java、JSP、RDBMS、Tomcat、HTML、Linux、JDBC、SVN

2、解决扩展性的问题:Struts、Spring、SpringMVC、Hibernate、Mybatis

3、解决性能的问题:NoSQL、Java线程、Hadoop、Nginx、MQ、ElasticSearch

★1.2 解决CPU及内存压力(面试题)

在这里插入图片描述

1.3 NoSQL数据库概述

NoSQL(NoSQL = Not Only SQL ),即“不仅仅是SQL”,泛指非关系型的数据库

NoSQL 不依赖业务逻辑方式存储,而以简单的key-value模式存储。因此大大的增加了数据库的扩展能力。

l 不遵循SQL标准。

l 不支持ACID。

l 远超于SQL的性能。

1.4 NoSQL适用场景

l 对数据高并发的读写

l 海量数据的读写

l 对数据高可扩展性的

1.5常用的NoSQL数据库
memcached
redis
mongodb
hbase
Cassandra
Neo4j


二. 认识Redis

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库

Ø Redis是一个开源的key-value存储系统。

Ø Redis可以用作数据库、缓存和消息中间件。

Ø Redis支持使用master-slave主从同步来实现高可用性,支持使用cluster集群来实现高性能。

在这里插入图片描述

三. 安装Redis

1)	准备工作:下载安装最新版的gcc编译器
 yum install gcc
gcc --version

2)	安装Redis
a.	下载redis-6.2.1.tar.gz放/opt目录
b.	解压命令:tar -zxvf redis-6.2.1.tar.gz
c.	解压完成后进入目录:cd redis-6.2.1
3)	在redis-6.2.1目录下再次执行make命令(只是编译好)
4)	跳过make test 继续执行: make install

四 访问Redis

Redis是C/S架构,分为Server和Client。需要先启动Server,再通过client访问

前台启动:

后台启动:(推荐)

[root@localhost redis-6.2.1]# mkdir /myredis

[root@localhost redis-6.2.1]# cp /opt/redis-6.2.1/redis.conf /myredis/

[root@localhost redis-6.2.1]# vim /myredis/redis.conf

daemonize no 修改为 daemonize yes 由前台启动变为后台启动

[root@localhost redis-6.2.1]# redis-server /myredis/redis.conf

访问★==[root@localhost redis-6.2.1]# redis-cli==

127.0.0.1:6379> ping

PONG

Redis是单线程+多路IO复用技

串行 vs 多线程+锁(memcached) vs 单线程+多路IO复用(Redis)

在这里插入图片描述

★五. Redis五大数据类型

在这里插入图片描述

1.Redis key 命令
keys 查看当前库所有key(匹配:keys *1)
del key 删除指定的key数据
expire key 10 10秒钟:为给定的key设置过期时间
flushdb清空当前库
flushall通杀全部库
2.Redis String命令

Integer、Double、String都认为是String,其实还可以是图片、视频等二进制数据

set 添加键值对
get 查询对应键值
incr
**decr **
incrby / decrby <步长>将 key 中储存的数字值增减。自定义步长。
getrange <起始位置><结束位置>
setex <过期时间>
3. Redis list命令

它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。

在这里插入图片描述

lpush/rpush  <key><value1><value2><value3> .... 从左边/右边插入一个或多个值。
lpop/rpop  <key>从左边/右边吐出一个值。值在键在,值光键亡。
lrange <key><start><stop>
lindex <key><index>按照索引下标获得元素(从左到右)
llen <key>获得列表长度 

linsert <key>  before <value><newvalue><value>的后面插入<newvalue>插入值

4.Redis set命令

set集合,底层结构是哈希表,速度快;无序,唯一

在这里插入图片描述

sadd <key><value1><value2> ..... 
将一个或多个 member 元素加入到集合 key 中,已经存在的 member 元素将被忽略
smembers <key>取出该集合的所有值。
srem <key><value1><value2> .... 删除集合中的某个元素。
sinter <key1><key2>返回两个集合的交集元素。
sunion <key1><key2>返回两个集合的并集元素。
sdiff <key1><key2>返回两个集合的差集元素(key1中的,不包含key2中的)

5.Redis hash命令

Redis是一个key-value的数据库。其中的value也可以是hash类型,value本身也是一个map,可以存储多个key-value

在这里插入图片描述

hset <key><field><value><key>集合中的  <field>键赋值<value>
hget <key1><field><key1>集合<field>取出 value 
hdel  <key><field> 删除<key>集合中指定<field>
hexists<key1><field>查看哈希表 key 中,给定域 field 是否存在。 
hincrby <key><field><increment>为哈希表 key 中的域 field 的值加上增量 1   -1

6.Redis zset命令

Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。

不同之处是有序集合的每个成员都关联了一个评分(score,这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合成员是唯一的,但是评分可以是重复了 。

zadd  <key><score1><member 1><score2><member 2>…

将一个或多个 member 元素及其 score 值加入到有序集 key 当中。

**zrange <key><start><stop>  [WITHSCORES]**   

返回有序集 key 中,下标在<start><stop>之间的元素

带WITHSCORES,可以让分数一起和值返回到结果集。

zrevrangebyscore key max min [withscores] [limit offset count]               

同上,改为从大到小排列。 

zincrby <key><increment><member >      为元素的score加上增量

六Redis 配置文件

在这里插入图片描述

七 使用Jedis访问Redis

使用Jedis连接Redis,确认连接成功

public class TestJedis {
    public static void main(String[] args) {
        //创建Jedis对象,指明Redis服务器的IP和port
        Jedis jedis = new Jedis("192.168.245.245",6379);
        //测试连接是否成功
        String result = jedis.ping();
        System.out.println(result);//PONG

        //关闭Jedis对象
        jedis.close();
    }
}

使用Jedis访问Redis

public class TestJedis2 {
    public static void main(String[] args) {
        //创建Jedis对象,指明Redis服务器的IP和port
        Jedis jedis = new Jedis("192.168.245.245",6379);
 //操作String
        jedis.set("k1","v1");
        jedis.mset("k2","v2","k3","v3");
        //操作key
        Set<String> keys = jedis.keys("*");
        System.out.println(keys);
        String value = jedis.get("k3");
        System.out.println(value);
 //操作List
        jedis.del("course");
        jedis.lpush("course","java","java","html","mysql");
        List<String> list = jedis.lrange("course", 0, -1);
        System.out.println(list);
          //操作Hash
        Map map = new HashMap();
        map.put("name","zhangsan");
        map.put("age","18");
        map.put("birthDate","1999-12-23");
        jedis.hset("zs",map);
//关闭Jedis对象
        jedis.close();
    }
}

使用Jedis连接池

public class TestJedis3 {
    public static void main(String[] args) {
        //指定Jedis连接池的配置信息
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(200);
        poolConfig.setMaxIdle(32);
        poolConfig.setMaxWaitMillis(100*1000);
        poolConfig.setBlockWhenExhausted(true);
        poolConfig.setTestOnBorrow(true);  // ping  PONG
        //创建Jedis对象,指明Redis服务器的IP和port
        //这是直接找服务器的上的Redis数据库建立物理连接,效率低下
        //可以考虑事先创建好多个物理连接,需要的时候直接拿来使用,效率高
        //Jedis jedis = new Jedis("192.168.245.245",6379);
        //创建连接池
        JedisPool jedisPool =
                new JedisPool(poolConfig, "192.168.245.245", 6379, 60000 );

        //从连接池中获取已经创建好的连接
        Jedis jedis = jedisPool.getResource();
        //测试连接是否成功
        String result = jedis.ping();
        System.out.println(result);//PONG

        //关闭Jedis对象
        jedis.close();
    }
}

八 手机验证码案例

在这里插入图片描述

public class PhoneCode {

    public static void main(String[] args) {
        //1.请输入手机号码
        Scanner input = new Scanner(System.in);
        System.out.println("请输入手机号码");
        String phone = input.next();
        //2.完成发送,并得到返回的验证码并输出
        System.out.println("输入1完成发送:");
        input.next();
        String code = getCode(phone);
        if("-1".equals(code)){
            System.out.println("本手机今天输入验证码已经超过3次,欢迎明天继续超过3次!!");
            return;
        }
        System.out.println("验证码是:"+code);

        //3.请输入验证码
        System.out.println("请输入验证码:");
        String myCode = input.next();

        //4.发送验证码,获取验证结果并输出
        System.out.println("输入1完成发送:");
        input.next();
        boolean flag = verifyCode(myCode,phone);
        if(flag){
            System.out.println("成功");
        }else{
            System.out.println("失败");
        }
    }
    /**
     * 验证验证码是否正确
     * @param myCode
     * @param phone
     * @return
     */
    private static boolean verifyCode(String myCode, String phone) {
        //从redis中获取验证码
        Jedis jedis = new Jedis("192.168.245.245",6379);
        String code = jedis.get("code:"+phone);

        //判断验证码是否正确
        boolean flag = false;
        if(code!=null && code.equals(myCode)){ //code可能是null吗???2分钟过期key不存在
            flag = true;
        }
        //返回结果
        return flag;
    }

    /**
     * 接收手机号码,生成验证码并返回
     * @param phone
     * @return
     */
    private static String getCode(String phone) {
        //生成验证码
        String code = generateCode();
        //验证码过期时间设为2分钟
        Jedis jedis = new Jedis("192.168.245.245",6379);
        jedis.setex("code:"+phone,120,code);
        //判断本手机验证码是否超过3次
        String count = jedis.get("count:" + phone);
        if(count==null){ //第一次访问
            //设置访问次数为1
            jedis.set("count:" + phone,"1");
        }else if(Integer.parseInt(count)<3){ //如果是第二次或者第三次访问
            jedis.incr("count:" + phone);
        }else{ //已经超过了3次
            code ="-1";
        }
        //返回验证码
        return code;
    }
    private static String generateCode() {
        Random random = new Random();
        String code = "";
        for(int i=0;i<6;i++) {
            int rand = random.nextInt(10);
            code += rand;
        }
        return code;
    }
}

九 Redis事务

Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

Redis事务的主要作用就是串联多个命令防止别的命令插队。

注意:此等重要的场合,对于事务的原子性闭口不提

Redis实现事务的三个命令:MultiExecdiscard

情况1: multi … 一切正常 discard 全部没有执行

情况2: multi … 一切正常 exec 全部正确执行

情况4:exec失败

在这里插入图片描述

没有保证所有操作的原子性

情况3:组队失败

在这里插入图片描述

如果在组队的时候失败,所有操作全部不执行,哪怕执行了exec。

十 乐观锁和悲观锁

1.悲观锁

在这里插入图片描述

悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。

传统的关系型数据库里边就用到了很多这种锁机制,比如行锁表锁等,读锁写锁等,都是在做操作之前先上锁。

2.乐观锁

在这里插入图片描述

乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的

3.Redis事务三特性

Ø 单独的隔离操作

n 事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

Ø 没有隔离级别的概念

n 队列中的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行

Ø 不保证原子性

n 事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

4.Redis事务和MySQL事务的区别
MySQL事务遵守严格的ACID特征,而Redis 设计更多的是追求简单与高性能,所以事务不会也没有必要受制于传统 ACID 的束缚。
	Redis 具备了一定的原子性,但不支持回滚,严格意义上无法保证原子性。
	Redis 不支持回滚,也就无法保证业务上的数据一致性。
	Redis 具备隔离性,但是没有隔离级别。
    Redis 通过一定策略可以保证持久性。Redis 是否具备持久化,取决于 Redis 的持久化模式比如AOF、RDB及其策略设置。

十一.秒杀思路

在这里插入图片描述

十二 秒杀实现

1.先来熟悉秒杀的代码

一个页面,一个Servlet,一个业务类,功能简单。关键在于业务类对Redis的操作

问题1:访问项目,提示连接超时:connect time out

原因:IP地址或者端口错误;防火墙开启;Redis服务器没有启动

模拟高并发秒杀功能:使用专门的工具:ab(apache benchmark) jmeter

\1. 安装ab yum install httpd-tools

\2. 使用ab:

ab -n 1000 -c 100 -k -p ~/postfile -T application/x-www-form-urlencoded http://192.168.15.51:8080/Seckill/doseckill

需要准备好postfile:内容:prodid=0101&

ab命令是linux上运行的,访问的windows tomcat上的项目,这是一个远程访问

访问地址要是windows tomcat上的资源的位置

2.问题:出现了超卖现象

在这里插入图片描述

3.原因:没有使用事务,也没有上锁

在这里插入图片描述

4.解决:在Jedis访问Redis的代码中使用乐观锁解决超卖问题

在这里插入图片描述

在这里插入图片描述

5.问题:超卖问题解决了,出现了库存有剩余的情况

原因:乐观锁。失败之后是否会重新发起请求继续秒杀

在这里插入图片描述

解决:LUA脚本

十三 主从复制

在这里插入图片描述

1.什么叫主从复制:

一个主机可以搭配多个从机,数据相同;从机会获取主机的数据

好处:

数据有冗余,即使主机出问题,从机中还有完整的数据。容灾

减轻主机的负担:读写分离

2. 如何实现一主二从

\1. 方法1:三台物理机

\2. 方法2:三台虚拟机

\3. 方法3:一台虚拟机,通过端口来区分 6379 6380 6381

3. 实现:
  1. 新建三个配置文件:

redis6379.conf redis6380.conf redis6381.conf

在这里插入图片描述

  1. 启动三台主机(没有主从关系)

[root@localhost myredis]# redis-server /myredis/redis6379.conf

[root@localhost myredis]# redis-server /myredis/redis6380.conf

[root@localhost myredis]# redis-server /myredis/redis6381.conf

[root@localhost myredis]# ps -ef | grep redis

root 1743 1 0 11:16 ? 00:00:00 redis-server *:6379

root 1749 1 0 11:16 ? 00:00:00 redis-server *:6380

root 1755 1 0 11:16 ? 00:00:00 redis-server *:6381

root 1761 1167 0 11:16 pts/0 00:00:00 grep --color=auto redis

[root@localhost ~]# redis-cli -p 6379

127.0.0.1:6379> info replication

# Replication

role:master

connected_slaves:0

master_failover_state:no-failover

master_replid:84fea270d109a28a6a3737580f0c212b15d65aa8

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:0

second_repl_offset:-1

repl_backlog_active:0

repl_backlog_size:1048576

repl_backlog_first_byte_offset:0

repl_backlog_histlen:0

[root@localhost ~]# redis-cli -p 6380

[root@localhost ~]# redis-cli -p 6381

在这里插入图片描述

  1. 建立主从关系:配从不配主

127.0.0.1:6380>slaveof 192.168.245.245 6379

OK

127.0.0.1:6380>info replication

# Replication

role:slave

master_host:192.168.245.245

master_port:6379

master_link_status:up

master_last_io_seconds_ago:7

master_sync_in_progress:0

slave_repl_offset:0

slave_priority:100

slave_read_only:1

connected_slaves:0

master_failover_state:no-failover

master_replid:37d530d2b5c08c108a14d93fb61e3e567ebd7faf

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:0

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:0

127.0.0.1:6380> keys *(拜完大哥立刻进行全量复制)

  1. “k2”

  2. “k1”

127.0.0.1:6380> keys *(主机的新增或者删除修改的内容会进行增量复制)

  1. “k2”

  2. “k1”

  3. “k3”

127.0.0.1:6380> keys *

  1. “k2”

  2. “k1”

127.0.0.1:6380> set k4 v4 (从机只能被读,不能写)

(error) READONLY You can’t write against a read only replica.

127.0.0.1:6380>

在这里插入图片描述

  1.   使用主从复制
    

主机挂掉,重启就行,一切如初

从机重启需重设:slaveof 127.0.0.1 6379

十四 主从复制-薪火相传

在这里插入图片描述

问题:中间的同时slave和master的服务器是否可以写???不可以!!!

风险是一旦某个slave(同时也是master)宕机,后面的slave都没法备份

十五 主从复制-反客为主

1. 手动

① 新大哥要手动的当大哥

② 小弟要手动的重新拜新大哥

③ 老大哥回来了,成立光杆司令,必须手动的拜新的大哥

如果这三个手动都变成自动,那该多好呀!!!

那就是哨兵机制,所有的这三个手动都有哨兵搞定。

1.2 复制原理:
l  slave启动成功连接到master后会发送一个sync命令

l  Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令, 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步

l  全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。

l  增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步

l  但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

十六 主从复制-哨兵模式

反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

在这里插入图片描述

①调整为一主二仆模式,6379带着6380、6381

② 自定义的/myredis目录下新建sentinel.conf文件并进行配置

sentinel monitor mymaster 127.0.0.1 6379 1

  1.   启动哨兵
    

redis-sentinel /myredis/sentinel.conf

④演示自动的反客为主

在这里插入图片描述

在这里插入图片描述

优先级在redis.conf中默认:replica-priority 100,值越小优先级越高

偏移量是指获得原主机数据最全的

每个redis实例启动后都会随机生成一个40位的runid(通过info server获取查看)

十七 集群

Redis3.0开始提供了解决方案,就是无中心化集群配置

在这里插入图片描述

Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。

一个集群最少3个主机,一个主机最少一个1个从机,搭建集群最少6台电脑

集群步骤
1. 配置6个conf文件,使用端口进行区分

| include /myredis2/redis.confpidfile “/var/run/redis_6379.pid”
port 6379
dbfilename “dump6379.rdb”

cluster-enabled yes
cluster-config-file nodes-6379.conf

cluster-node-timeout 15000
cluster-enabled yes    打开集群模式

cluster-config-file nodes-6379.conf  设定节点配置文件名

cluster-node-timeout 15000   设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换。
2. 启动6个主机
[root@localhost myredis2]# redis-server /myredis2/redis6379.conf 
[root@localhost myredis2]# redis-server /myredis2/redis6380.conf 
[root@localhost myredis2]# redis-server /myredis2/redis6381.conf 
[root@localhost myredis2]# redis-server /myredis2/redis6389.conf 
[root@localhost myredis2]# redis-server /myredis2/redis6390.conf 
[root@localhost myredis2]# redis-server /myredis2/redis6391.conf 
[root@localhost myredis2]# ps -ef | grep redis
root       2427      1  0 14:44 ?        00:00:00 redis-server *:6379 [cluster]
root       2433      1  0 14:45 ?        00:00:00 redis-server *:6380 [cluster]
root       2439      1  0 14:45 ?        00:00:00 redis-server *:6381 [cluster]
root       2445      1  0 14:45 ?        00:00:00 redis-server *:6389 [cluster]
root       2451      1  0 14:45 ?        00:00:00 redis-server *:6390 [cluster]
root       2457      1  0 14:45 ?        00:00:00 redis-server *:6391 [cluster]
root       2463   1167  0 14:45 pts/0    00:00:00 grep --color=auto redis

在这里插入图片描述

3. 通过命令搭建集群

redis-cli --cluster create --cluster-replicas 1
192.168.245.245:6379 192.168.245.245:6380 192.168.245.245:6381
192.168.245.245:6389 192.168.245.245:6390 192.168.245.245:6391

在这里插入图片描述

在这里插入图片描述

十八 RDB持久化

1. RDB(RedisDataBase)

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失

在这里插入图片描述

在这里插入图片描述

配置文件名称dbfilename:默认为dump.rdb

配置文件位置 dir:rdb文件的保存路径,默认为Redis启动时命令行所在的目录下

持久化策略:格式:save 秒钟 写操作次数

RDB是整个内存的压缩过的Snapshot,RDB的数据结构,可以配置复合的快照触发条件,默认是1分钟内改了1万次,或5分钟内改了10次,或15分钟内改了1次

如果取消持久化
save “”

2.如何触发RDB快照

① save策略

\2. 手动save和bgsave

③ flushall

④ shutdown正常关闭redis

3.优势

l 适合大规模的数据恢复

l 对数据完整性和一致性要求不高更适合使用

l 节省磁盘空间

l 恢复速度快

十九 AOF持久化

1. 概念

日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录), 只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据

注意:会记录整个的写操作过程(写、删除、修改)。文件越来越大。

默认AOF不开启:appendonly no

默认

AOF

文件

appendfilename “appendonly.aof”

AOF和RDB同时开启,系统默认取AOF的数据(rdb可能丢失最后一次持久化的内容)

2. AOF持久化流程

(1)客户端的请求写命令会被append追加到AOF缓冲区内;没有写入文件呢??

(2)AOF缓冲区根据==AOF持久化策略[always,everysec,no]==将操作sync同步到磁盘的AOF文件中;

(3)AOF文件大小超过==重写策略或手动重写(rewrite==时,会对AOF文件rewrite重写,压缩AOF文件容量;

(4)Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;

3. AOF持久化策略:

appendfsync always 随时持久化

appendfsync everysec 每秒持久化一次

# appendfsync no 不(主动)持久化

4.AOF重写策略

auto-aof-rewrite-percentage:设置重写的基准值,文件达到100%时开始重写(文件是原来重写后文件的2倍时触发)

auto-aof-rewrite-min-size:设置重写的基准值,最小文件64MB。达到这个值开始重写。

10M---->20M---->40M—80M(>64M)

5. AOF如何重写

redis4.0版本后的重写,是指上就是把rdb 的快照,以二级制的形式附在新的aof头部,作为已有的历史数据,替换掉原来的流水账操作

RDB中存储key-value的最后的值,但是AOF存对key-value的操作过程(delete、set)

dump.rdb是二进制文件,不可读;但是aof文件是文本文件,可读

优势

①appendfsync always 备份机制更稳健,丢失数据概率更低

②可读的日志文本,通过操作AOF稳健,可以处理误操作

6. 到底使用RDB还是使用AOF
① 两个都不用:只是做纯内存缓存

② 使用RDB:对数据不敏感

③ 同时使用RDB和AOF:可以弥补RDB对数据不敏感

④不建议单独使用AOF

*2. AOF**持久化流程

(1)客户端的请求写命令会被append追加到AOF缓冲区内;没有写入文件呢??

(2)AOF缓冲区根据==AOF持久化策略[always,everysec,no]==将操作sync同步到磁盘的AOF文件中;

(3)AOF文件大小超过==重写策略或手动重写(rewrite==时,会对AOF文件rewrite重写,压缩AOF文件容量;

(4)Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;

3. AOF持久化策略:

appendfsync always 随时持久化

appendfsync everysec 每秒持久化一次

# appendfsync no 不(主动)持久化

4.AOF重写策略

auto-aof-rewrite-percentage:设置重写的基准值,文件达到100%时开始重写(文件是原来重写后文件的2倍时触发)

auto-aof-rewrite-min-size:设置重写的基准值,最小文件64MB。达到这个值开始重写。

10M---->20M---->40M—80M(>64M)

5. AOF如何重写

redis4.0版本后的重写,是指上就是把rdb 的快照,以二级制的形式附在新的aof头部,作为已有的历史数据,替换掉原来的流水账操作

RDB中存储key-value的最后的值,但是AOF存对key-value的操作过程(delete、set)

dump.rdb是二进制文件,不可读;但是aof文件是文本文件,可读

优势

①appendfsync always 备份机制更稳健,丢失数据概率更低

②可读的日志文本,通过操作AOF稳健,可以处理误操作

6. 到底使用RDB还是使用AOF
① 两个都不用:只是做纯内存缓存

② 使用RDB:对数据不敏感

③ 同时使用RDB和AOF:可以弥补RDB对数据不敏感

④不建议单独使用AOF
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值