• redis


    1. redis基础
    2.linux下启动redis
    3.Redis的数据类型
    4.常用命令
    5.通用命令
    6.使用jedis操作redis
    7.SpringData操作mysql数据库
    8.Redis持久化
    9.主从复制
    10.哨兵模式–主节点发生问题,子节点变为主节点
    11.redis海量数据,海量写 ----- 分片集群
    12.多级缓存
    13.Lua语法
    14.Redis预热
    15.缓存同步

    Redis 基础

    Redis 是基于内存的key-value结构数据库
    1.基于内存存储没读写性能高
    2.存储热点数据(热点商品、新闻)
    3.应用广泛
    
    • 1
    • 2
    • 3
    • 4

    Nosql,数据与数据之间没有任何关系,非关系型数据库
    缓存、消息队列

    linux下启动redis

    安装: make可用make MALLOC=libc替换使用
    在这里插入图片描述当前目录下:./redis-server 启动redis

    cd /usr/local/redis-4.0.0/src 找到src目录
    ./redis-cli 启动程序

    修改redis的配置文件
    vim redis.conf 修改daemonize yes
    src/redis-server ./redis.conf
    可以让redis砸在后台运行

    密码校验

    修改 redis.conf的密码 requirepassword
    重新启动该文件
    ps -ef | grep redis 查看进程
    kill -9 23789 杀掉该进程
    src/redis-server ./redis.conf 重新启动该配置文件
    src/redis-cli -h localhost -p 6379 启动redis
    auto 输入密码
    exit 退出

    远程连接

    redis.conf # 掉
    在这里插入图片描述
    ps -ef | grep redis 查询redis的端口号
    kill -9 70771 杀掉端口号
    src/redis-server ./redis.conf 重新启动
    firewall-cmd --reload 关闭防火墙
    firewall-cmd --add-port=6379/tcp 开放端口
    windows就可以通过
    .\redis-cli.exe -h ip -p 端口 -a 密码

    常用数据类型

    key为string,
    value为:

    1. String 字符串类型
    2. hash 哈希 适合存储对象
    3. list 列表,没有重复元素
    4. set 集合,没有重复元素,相同的元素会被覆盖掉
    5. sorted set 有序集合,没有重复元素,相同的元素会被覆盖掉

    常用命令

    字符串常用命令

    1. set key value 设置指定的key
    2. get key 获取指定的key
    3. setex key 时间 value 设置指定的key的值,中间设置过期时间
    4. setnx key value 只要key不存在,设置

    hash操作命令

    1. HSET key1 key2 value 将哈希表key1字段 key2 和value设置为值

    2. HGET key1 key2 根据哈希表key1获取key2 的value在这里插入图片描述

    3. HDEL key value1,value2 删除哈希表key1的 key2的指定字段

    4. HKEYS key1 获取哈希表key1的所有的字段

    5. HVALS key1 获取哈希表key1的所有字段的值

    6. hgetall key1 获取哈希表key1的所有字段和值

    列表 每一个列表都是字符串类型的

    1. LPUSH key value 插入到头部 先插入的数据在尾部
    2. LRANGE key 范围(x 空格 x) 获取元素 ,获取的数据是后插入的数据
    3. rpop key 移除并获取最后一个元素 移除最早插入的数据
    4. llen key 获取元素长度
    5. brpop key timeout 移除并获取最后一个元素,如果当前没有删除的元素,则等待设置的时间

    set集合 唯一 无序的集合

    1. SADD KEY 元素1 元素2 ->添加元素
    2. SMEMBERS key ->返回集合中的所有成员
    3. SCARD key ->获取所有成员的个数
    4. SINTER KEY KEY2 ->返回所有集合的交集(两个集合相同的)
    5. SUNION KEY1 KEY2 ->返回所有集合的并集(两个集合相加,相同的排除)
    6. SDIFF KEY1 KEY2 ->返回所有指定集合的差集 (第一个减去第二个集合剩余的数据)
    7. SREM key name1 name2 ->移除集合一个或多个成员

    sorted set 有序集合
    有序集合是string类型的集合,不允许重复数据,每一个元素都会关联一个double类型的分数,redis通过分数进行集合中从大到小的排序,有序集合的成员是唯一的,分数可以重复.

    1. zadd key 值 元素 值 元素 新增sorted set集合
    2. zrange key 值 值 从小到大查询两个数字之间的元素 withscores(显示值元素)
    3. zincrby key 值 元素 增加分数
    4. zrem key 移除元素

    通用命令

    1. keys * 查询有多少key
    2. exists key 查看key是否存在
    3. type key 返回key所存储的类型
    4. ttl key 返回给定的key 的剩余生存时间
    5. DEL key 删除指定的key
    6. flushall 清除所有缓存

    java中操作redis->jedis

    @SpringBootTest
    class DemoApplicationTests {
    
        /**
         *         
         *             redis.clients
         *             jedis
         *             2.8.0
         *         
         */
        @Test
        void contextLoads() {
            //1.获取连接
            Jedis jedis = new Jedis("localhost",6379); //本地
            //2.执行具体的操作
            jedis.set("name","xiaowang"); //新增
            //3.关闭连接
            jedis.close();
        }
    
        @Test
        void TestJedis(){
            Jedis jedis = new Jedis("localhost",6379); //本地
            String s = jedis.get("name"); //查询
            System.out.println(s);
        }
    
        @Test
        void Del(){
            Jedis jedis = new Jedis("localhost",6379); //本地
            Long name = jedis.del("name"); //删除
            System.out.println(name);
        }
    
    
        @Test
        void Hash(){
            Jedis jedis = new Jedis("localhost",6379); //本地
    //        Long hset = jedis.hset("1001", "name", "xiaowang");
            String hget = jedis.hget("1001", "name");
            System.out.println(hget);
    //        System.out.println(lrange);
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    使用springdata操作redis

         依赖
            org.springframework.boot
            spring-boot-starter-data-redis
        
    
    • 1
    • 2
    • 3
    • 4

    String类型的操作

    @Autowired
        private RedisTemplate redisTemplate;
    
        /**
         *  操作string的数据
         */
        @Test
        public void Test01(){
            // 获取String对象
            ValueOperations valueOperations = redisTemplate.opsForValue();
            valueOperations.set("name1","xiaoye");
            String name = (String)valueOperations.get("name1");
            // 设置十秒钟的过期时间
            redisTemplate.opsForValue().set("age","10",111l, TimeUnit.SECONDS);
            // 不存在时,设置key
            Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("name2", "xiaowang");
            System.out.println(aBoolean);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Hash的操作

    /**
         *  操作Hash类型的数据
         */
        @Test
        public void Hash(){
            HashOperations hashOperations = redisTemplate.opsForHash();
            //存值
            hashOperations.put("01","11","xiaowang");
            hashOperations.put("01","12","xiaoye");
            //取值
            String o =(String) hashOperations.get("01", "11"); //获取key为01的11的值
            String o1 =(String) hashOperations.get("01", "12");
            System.out.println(o);
            System.out.println(o1);
            //获取Hash结果中所有的字段
            Set keys = hashOperations.keys("01");
            for (Object j : keys){
                System.out.println(j);
            }
            //获取Hash结构中所有的值
            List values = hashOperations.values("01");
            for (Object j : values){
                System.out.println(j);
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    List的操作

      /**
         *  操作list的数据
         */
        @Test
        public void List(){
            ListOperations listOperations = redisTemplate.opsForList();
            // 存入list单个数据
            listOperations.leftPush("1","a");
            //存入list多个数据
            listOperations.leftPushAll("1","b","c","d");
            //查询所有元素
            List<String> range = listOperations.range("1", 0, -1);
            for (String s :range){
                System.out.println(s);
            }
            //获取集合的长度
            Long size = listOperations.size("1");
            int i = size.intValue();
            for (int i1 = 0; i1 < i; i1++) {
                //移除集合最后一个元素
                String o =(String) listOperations.rightPop("1");
                System.out.println("删除当前元素"+o+"执行"+i1+"次");
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    set的操作方法

    /**
         *  Set 类型的操作
         */
        @Test
        public void Set(){
            SetOperations setOperations = redisTemplate.opsForSet();
            //Set存值
            setOperations.add("123","123","456");
            // 删除
            setOperations.remove("123","123");
            //Set取值
            Set<String> members = setOperations.members("123");
            for (String c : members){
                System.out.println("Set的值为:"+c);
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    zset的操作方法

    /**
     *  sorted set 有序集合,不能重复
     */
    @Test
    public void sortedSet(){
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        //存值
        zSetOperations.add("zset","a",1);
        zSetOperations.add("zset","b",2);
        zSetOperations.add("zset","c",1.5);
        //取值
        Set<String> zset = zSetOperations.range("zset", 0, -1);
        for (String s : zset){
            System.out.println("第一组"+s);
        }
        //修改分数
        zSetOperations.incrementScore("zset","a",10);
        Set<String> zset1 = zSetOperations.range("zset", 0, -1);
        for (String s : zset1){
            System.out.println("第二组"+s);
        }
        //删除分数
        zSetOperations.remove("zset","a","b");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    通用操作

    /**
     * 通用操作
     */
    @Test
    public void tets(){
        // 获取redis中所有的key
        Set<String> keys = redisTemplate.keys("*");
        for (String s : keys){
            System.out.println("获取所有的key"+s);
        }
    
        //判断某个key是否存在
        Boolean zset = redisTemplate.hasKey("zset");
        System.out.println("当前key是否存在"+zset);
    
        //删除指定的key
        Boolean zset1 = redisTemplate.delete("zset");
        System.out.println("当前是否删除"+zset1);
    
        // 获取指定key对应的value的数据类型
        DataType type = redisTemplate.type("123");
        String name = type.name();
        System.out.println("获取指定的key"+name);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    主从复制 持久化

    在这里插入图片描述

    RDB持久化

    • RDB方案在redis内部开启了,每次服务器关闭时,执行一次Save,完成一次RDB操作
    • 可用设置RDB的设置,如多少秒执行一次
    • save主进程(主进程执行,其他操作不能执行) bgsave 子进程

    原理:

    在这里插入图片描述

    AOF持久化

    • 在conf文件设置
      在这里插入图片描述

    AOF执行的每一次操作,经过设定的同步秒数(默认为1),写在定义的文件中,如果服务器突然关闭,读取这个文件即可恢复数据。

    • 压缩文件–触发重写
      在这里插入图片描述

    RDP与AOF的不同

    在这里插入图片描述

    主从复制

    在这里插入图片描述

    • 将B设置为A的子节点

    在这里插入图片描述

    • 同步原理
      在这里插入图片描述

    • 全量同步原理(主节点判断replid是否一致,id不一致为第一次,从节点拉取主节点版本信息,主节点执行bgsave,生成RDB文件,发送给从节点,从节点删除本地文件,加载文件,如果当前发生了数据操作,主节点添加repl_baklog,并将log中的命令发生给从节点,从节点接收命令,执行命令,这样完成与主节点的同步)
      在这里插入图片描述

    • 增量同步(主节点判断replid是否一致,id一致为不是第一次,从节点从主节点repl_baklog文件中同步尚未同步的数据)

    在这里插入图片描述

    • 区别
      在这里插入图片描述

    哨兵管理

    ****当主节点发送异常时,推选其他从节点为主节点,将异常主节点修改为从节点 ****
    在这里插入图片描述
    在这里插入图片描述

    redisTemplate使用哨兵模式

    在这里插入图片描述

    配置集群的读写分离

    在这里插入图片描述

    分片集群

    计算当前操作的哈希值,分配到不同的redis进行存储
    在这里插入图片描述

    故障转移

    **主节点出现问题后,主节点拒绝所有数据访问,主节点向从节点发送offset数据,判断从节点数据是否同步,同步的话进行数据迁移,子节点标注自己为主节点,向其他从节点广播自己的主节点,收到广播后,处理用户的请求,宕机的主节点恢复后,变为从节点 **
    在这里插入图片描述

    多级缓存

    JVM的进程缓存

    redis和本地缓存搭配使用
    在这里插入图片描述
    jvm缓存查询
    在这里插入图片描述
    设置jvm缓存
    在这里插入图片描述

    • 代码实现
    public class CaffeineTest {
    
        /*
          基本用法测试
         */
        @Test
        void testBasicOps() {
            // 创建缓存对象
            Cache<String, String> cache = Caffeine.newBuilder().build();
    
            // 存数据
            cache.put("gf", "迪丽热巴");
    
            // 取数据,不存在则返回null
            String gf = cache.getIfPresent("gf");
            System.out.println("gf = " + gf);
    
            // 取数据,不存在则去数据库查询
            // 先查询key为"defaultGF"的数据,如果不存在,则查询数据库的数据,也就是key方法体的数据
            String defaultGF = cache.get("defaultGF", key -> {
                // 这里可以去数据库根据 key查询value
                return "柳岩";
            });
            System.out.println("defaultGF = " + defaultGF);
        }
    
        /*
         基于大小设置驱逐策略:
         */
        @Test
        void testEvictByNum() throws InterruptedException {
            // 创建缓存对象
            Cache<String, String> cache = Caffeine.newBuilder()
                    // 设置缓存大小上限为 1
                    .maximumSize(1)
                    .build();
            // 存数据
            cache.put("gf1", "柳岩");
            cache.put("gf2", "范冰冰");
            cache.put("gf3", "迪丽热巴");
            // 延迟10ms,给清理线程一点时间
            Thread.sleep(10L);
            // 获取数据
            System.out.println("gf1: " + cache.getIfPresent("gf1"));
            System.out.println("gf2: " + cache.getIfPresent("gf2"));
            System.out.println("gf3: " + cache.getIfPresent("gf3"));
        }
    
        /*
         基于时间设置驱逐策略:
         */
        @Test
        void testEvictByTime() throws InterruptedException {
            // 创建缓存对象
            Cache<String, String> cache = Caffeine.newBuilder()
                    .expireAfterWrite(Duration.ofSeconds(1)) // 设置缓存有效期为 10 秒
                    .build();
            // 存数据
            cache.put("gf", "柳岩");
            // 获取数据
            System.out.println("gf: " + cache.getIfPresent("gf"));
            // 休眠一会儿
            Thread.sleep(1200L);
            System.out.println("gf: " + cache.getIfPresent("gf"));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    在这里插入图片描述

    在这里插入图片描述

    LUA

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    Redis预热功能

    在这里插入图片描述

    缓存同步 Canal

    • mysql在进行增删改时,会将日志记录在binary log 目录中 ,slave会开启线程读取文件,放入relay log中,再开启线程去读log中操作,canal伪装成一个slave节点,完成相应的操作

    • 加入jar包
      在这里插入图片描述

    • 配置监听器,监听sql操作

    在这里插入图片描述

    • 标记表中的字段
      在这里插入图片描述

    多级缓存总结

    在这里插入图片描述

  • 相关阅读:
    Jmeter参数化 —— 循环断言多方法
    C基础知识-结构体(详解)
    超硬核解析!Apache Hudi灵活的Payload机制
    基于非链式(数组)结点结构的二叉树的前(先)序输入创建以及遍历
    基于PHP+MySQL的企业宣传展示网
    【vue会员管理系统】篇五之系统首页布局和导航跳转
    三菱PLC FX3U脉冲轴回原功能块(MC_Home_P)
    使用Nodejs搭建简单的HTTP服务器 - 内网穿透公网远程访问
    Java中如何判断字符串输入[hello,world]是不是字符串数组参数
    Python中集合的使用方法2-1
  • 原文地址:https://blog.csdn.net/qq_48690030/article/details/127834160