Redis学习笔记

1. Nosql

1.特点

方便扩展、大数据量高性能、数据类型是对样的

2、四大分类

1、KV键值对

2、文档型数据库

3 、列存储数据库

4、图关系数据库

优缺点对比

2.Redis

内存中的数据结构存储系统,可以用作数据库,缓存和消息中间件

远程字典服务,Key_Value数据库

redis功能:内存存储、持久化(rdb,aof)

2.1、redis安装及运行(linux)

9、Linux下安装Redis详解_哔哩哔哩_bilibili

cd usr/local/bin、 redis-server Kconfig/redis.conf 、 redis-cli -p 6379

退出:shutdown 、 quit

2.2性能测试

redis-benchmark -h localhost -p 6379 -c 100 -n 100000(测试100个并发连接,并且每个并发连接100000个请求)

查看分析如下:

2.3基础知识 

默认使用的是第0个数据库,可以用select来进行切换

keys * 查看当前数据库所有的key ;flushdb 清除当前数据库 ;move [name] 移除当前的key ;

EXPIRE [name] 10 name10秒后过期 ; ttl [name] 查看name还有多长时间过期;

type [name]  查看name是什么类型的

命令可以再redis官网中的命令进行查询学习:

redis是单线程的(基于内存)

redis的瓶颈是与机器的内存和网络带宽相关,与cpu无关。

redis为什么单线程还这么快

核心:redis是将数据存放到内存中的,所以使用单线程操作效率最高,多线程中cpu上下文会切换:耗时的操作

2.4  五大数据类型

2.4.1 String(value可以是字符串或者数字)

APPEND [name]  "avdfg"  拼接字符串;GETRANGE [name] 0 3 截取0-3的字符串

DECRBY [name] 10 以步长为10执行降低;SETRANGE [name] 1 xx 替换指定位置开始的字符串

setnx(分布锁中会经常用到)

 值相当于json字符串来保存一个对象,很巧妙的设计

 getset [name] "asfa” 先get在set

应用场景:计数器、统计多单位的数量、粉丝数、对象缓存存储

2.4.2 List

在Redis中,list可以变成栈、队列、阻塞队列

list命令以l开头的

LPUSH(RPUSH ) list [one] (添加)、

LRANGE list 0 2 (查看)、

lindex list 2(查看) 、

lpop(rpop) list (移除) 、

rpoplpush list otherlist(移动元素)、

Linsert list before(after)  "we" "ewr3e"   (在某位置插入元素ewr3e)

lrem list 2 three:移除两个three

注(上面的list是创建的list名称,用户可以自由修改)

小结

list相当于一个链表

使用场景:消息排队! 消息队列(lpush,rpop),栈(lpush,lpop)

 2.4.3 set集合(没有重复元素)

         命令以s开头( sadd myset "xx"  (添加);    SMEMBERS myset (查看) ;SISMEMBER myset "xx" (判断是否存在) ; srem myset "xx" (移除元素) ;SRANDMEMBER myset 2 (随机挑选2个元素) ;spop myset (随机删除元素);setmove myset myset2 “xx” (移动元素))

         交并补:sdiff set1 set2 (不同元素) ;sinter set1 set2 (交集);sunion set1 set2 (并集)

应用场景:共同好友,用户关注博主等

2.4.4 hash(哈希)

Map集合,key-value 这个值是一个map集合

命令以h开头(hset 、hget 、hmset(批量添加)、hmget 、hsetall(获取所有值)、hdel (删除指定的key字段)hlen (获取长度))

 注意:  hash变更的数据user name age ,尤其是用户信息之类的,经常变动的信息,hash更适合对象的存储,string更适合字符串的存储

2.4.5 zset(有序集合)

命令以z开头 (zset set1 2 xx (2是设置的排序)、zrem (移除制定元素)、zcard (获取元素个数)、zcount (获取在指定区间内的成员数量))

案例思路:set 排序 存储班级成绩表,工资表排序,排行榜应用实现

2.5 三种特殊类型

2.5.1 geospatial 地理位置

geoadd list1 经度 纬度 名称  :写入定位

geopos list1 名称 :获得当前定位

geodist list1 名称1 名称2 :两地直线距离

georadius list1 经度 纬度 半径 单位 :附近的元素

GEO底层的实现原理是Zset         

2.5.2 Hyperloglog

基数统计的算法

优点:占用的内存是固定,从内存角度比较hyperloglog首选(传统的采用set统计判断用户数据)

命令( pfadd list1 xx xx ;pfcount list1 ; pfmerge list3 list1 list2 (合并到list3中))

如果允许容错,一定采用hyperloglog

如果不允许容错,使用set或者自己的数据类型即可

2.5.3 Bitmaps(位图)

操作二进制来存储,只有0,1两种状态

位存储

统计用户信息,(不)活跃,(未)登录 两个状态的,都可以使用bitmaps

命令:( setbit (记录); getbit(查看); bitcount(统计))



2.6基本事务操作

2.6.1 基础知识

redis事务本质:一组命令的集合,执行过程中,会按照顺序进行(一次性、顺序性、排他性)

原子性:要么同时成功,要么同时失败

(redis中单条命令保存原子性,但是事务不保证原子性)

事务流程:开启事务(multi)、命令入队、执行事务(exec)        (放弃事务(discard))

2.6.2 乐观锁

 redis测监视测试(watch) 

测试多线程修改值,使用watch可以当做redis的乐观锁操作   面试常问

2.7 JRedis

 REDIS官方推荐的Java连接并发工具,使用java操作Redis中间件

 2.7.1测试

1、导入依赖

2.编码测试

连接数据库

操作命令

断开连接

 2.7.2 事务(再次理解)

public static void main(String[] args) {
        //创建客户端连接服务端,redis服务端需要被开启
        Jedis jedis = new Jedis("192.168.1.131", 6379);
        jedis.flushDB();

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("hello", "world");
        jsonObject.put("name", "java");
        //开启事务
        Transaction multi = jedis.multi();
        String result = jsonObject.toJSONString();
        try{
            //向redis存入一条数据
            multi.set("json", result);
            //再存入一条数据
            multi.set("json2", result);
            //这里引发了异常,用0作为被除数
            int i = 100/0;
            //如果没有引发异常,执行进入队列的命令
            multi.exec();
        }catch(Exception e){
            e.printStackTrace();
            //如果出现异常,回滚
            multi.discard();
        }finally{
            System.out.println(jedis.get("json"));
            System.out.println(jedis.get("json2"));
            //最终关闭客户端
            jedis.close();
        }
    }

 2.8 springboot整合redis(redis-springboot)

1、导入依赖

<!--操作redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2、配置连接

#Springboot所有的配置类,都有一个自动装配类   **AutoConfiguration
#自动装配类会绑定一个 properties 配置文件 **Properties
spring.redis.host=127.0.0.1
spring.redis.port=6379

3、测试

@Autowired
//    这是注入在RedisAutoConfiguration中配置的类
     private RedisTemplate redisTemplate;
    @Test
    void contextLoads() {

        //redisTemplate  opsForValue操作字符串   opsForList操作List  opsForGeo等
        //除了基本的操作,我们常用的方法都可以通过redisTemplate操作,比如事务和基本的增删改查等

        //获取连接
//        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//        connection.flushDb();
//        connection.flushAll();

        redisTemplate.opsForValue().set("mykey","wuhu");
        System.out.println(redisTemplate.opsForValue().get("mykey"));

    }

4。自定义RedisTemplate

@Configuration
public class RedisConfig {

    //这是固定模板,在企业中,可以直接使用
    /*编写自己的配置类redisTemplate*/
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String , Object> redisTemplate(RedisConnectionFactory factory) {
        //为了开发方便,一般直接使用<String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);

        //Json序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //string的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        //配置具体的序列化方式
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }


}

 

 5、创建工具类,方便使用    utils包下

在真实开发中,自己封装RedisUtil ,将一些常用的方法封装,然后可以在使用的时候注入

2.9、Redis.conf详解

(仅仅是了解配置文件,不做修改)redis配置文件

在虚拟机中的usr/local/usr/Kuangshen/redis.conf中

 快照(持久化,在规定的时间内,执行了可多少次操作,则可持久化到.rdb .aof)

 

 客户端限制(clients)

 

 2.10  Redis持久化

面试和工作的重点 

redis是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以redis提供了持久化功能

2.10.1 RDB

是指用数据集快照的方式半持久化模式)记录 redis 数据库的所有键值对,在某个时间点将数据写入 一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。

优点: 只有一个文件 dump.rdb ,方便持久化; 容灾性好,一个文件可以保存到安全的磁盘; 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 Redis 的高性能) ;适合大规模的数据恢复对数据的完整性要求不高

缺点: 数据安全性低。 RDB 是间隔一段时间进行持久化,如果持久化之间 Redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候;fork进程的时候,会占用一定的空间

触发机制

恢复rdb文件 

 

2.10.2 ROF

将所有命令记录下来,恢复的时候把文件执行一遍

aof文件出错:如果这个aof文件有错误,这时候Redis启动不了,我们需要修复这个aof文件。用redis-check-aof --fix修复  (redis-check-aof --fix appengonly.aof

优点

数据安全, AOF 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 AOF 文件中一次

缺点

AOF 文件比 RDB 文件大,且恢复速度慢;数据集大的时候,比 RDB 启动效率低

重写规则

如果文件大于64m,fork一个新的进程

2.11 Redis发布订阅

 测试(publish、subscribe、psubscribe)

发送端

订阅端

 

使用场景

实时消息系统、实时聊天(频道当聊天室)、订阅关注系统

稍微复杂的场景会使用消息中间件MQ

 

2.12 Redis主从复制

       一个主服务器的数据复制到其他多个从服务器;数据的复制是单向的;读写分离,80%在进行读操作

2.12.1主从复制的作用

数据冗余、故障恢复、负载均衡、高可用基石

2.12.2 环境配置(伪集群,在一台电脑上)

只配置从库,不用配置主库

 1.复制3个配置文件,然后修改对应的信息(端口,pid名字,日志名称,dmp名称)

2.认主机 SLAVEOF 127.0.0.1(主机地址) 6379(主机端口) 

2.12.3 细节

1、主机可以写,从机不能写只能读! 主机的信息自动被从机保存

2、主机断开连接,当主机再次连接时,从机依旧可以获取主机写的信息

3、如果命令行来配置的主从,如果重启,会变为主机!只要变为从机,一次全量复制将被自动执行

如果主机宕机了,对从机手动配置设置为主机(SLAVEOF no one

2.12.4 哨兵模式(自动选举主机)

      哨兵是独立的进程,哨兵对redis服务器发命令,让服务器返回运行状态 ;当检测主机宕机,会自动将主机切换为从机,然后通过发布订阅模式通知其他的从服务器,修改配置文件,切换主机

测试

1. 在Kconfig文件夹下新建sentinel.conf文件,并写入sentinel monitor myredis(被监控的名称) 127.0.0.1(host) 6379(port) 1(投票)

2.在bin目录下运行redis-sentinel Kconfig/sentinel.conf命令,打开哨兵模式

3.如果master断开,则会在从集中随机选择一个服务器(投票算法)

4.如果此时主机重新回来了,只能归并到新的主机下,当做从机

优点:

缺点:

 全部配置

 

2.13 Redis缓存穿透和雪崩(面试高频)

2.13.1 缓存穿透(查不到导致的)

 解决方案

1.布隆过滤器

2、缓存空对象

2.13.2 缓存击穿(量太大,缓存过期导致的)

 解决方案

1.设置热点数据永不过期

2、加互斥锁

 2.13.3 缓存雪崩

解决方案

redis高可用、限流降级、数据预热

 

补充:

linux:狂神说Linux02:常用的基本命令(必掌握)狂神说Linux03:Vim使用及账号用户管理狂神说Linux04:三种软件安装方式及服务器基本环境搭建

将springboot项目打包并在linux上运行:15、rpm安装jdk上线项目_哔哩哔哩_bilibili

打开端口、重启防火墙、查看所有开启的端口、访问

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值