redis入门

本文深入解析Redis非关系型数据库的特点,包括其数据结构、应用场景、安装配置、与Java及Spring框架的集成,以及缓存、分布式锁、Lua脚本等高级功能。探讨Redis的持久化策略、内存回收机制和集群部署方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、什么是Redis?

 

    redis是一款非关系型数据库(NoSql,not only sql - 不仅仅是sql),数据存放结构是按照key-value类型存放的,而且数据是保存在内存中的,相对于传统的关系型数据库(数据放在硬盘上),数据的读写速度非常的快(10W/s),另外相对于其他的 数据库,Redis也提供了持久化的功能,但是相对于传统的关系型数据库,数据安全性没有那么可靠,而且数据存放的大小也比不上关系型数据库,因此在实际开发过程中,项目既会用到关系型数据库也会用到非关系型数据

 

 

二、Redis的运用场景

 

    1)作为缓存服务器(常见)

        

 

    2)处理高速读写时的数据一致性问题

        

 

    3)进行数据共享

        

 

    4)分布式锁

        

 

    5)分布式序号递增

        

 

 

三、Redis的安装

 

    基本的安装过程

        解压:tar -zxf redis-3.2.4.tar.gz

        进入解压包:cd redis-3.2.4

        编译安装:

            make

            make install

 

        启动redis

            cd src

            ./redis-server

        注意:当前会默认按照前台进程的方式启动redis

 

    设置redis的后台进程的启动方式

        拷贝配置文件:cp ../redis.conf ./

        修改配置文件:vim redis.conf

        

 

        启动redis:./redis-server redis.conf

 

    设置redis的远程连接模式

        开放6379的端口

        修改配置文件:vim redis.conf

        

        

 

四、Java如何操作Redis

 

    1)添加依赖

    <dependency>

        <groupId>redis.clients</groupId>

        <artifactId>jedis</artifactId>

        <version>3.0.1</version>

    </dependency>

 

    2)编写代码

    

 

五、Spring如何操作Redis

 

    1)添加依赖

    

 

    2)添加Spring的配置文件

    

 

    3)使用Spring

    

 

    注意:Spring提供了一个模板对象,该模板对象默认会对设置的值进行序列化和反序列化

 

六、SpringBoot如何操作Redis

 

    1)添加依赖

    

 

    2)配置application.yml

    

 

    3)使用redis

    

 

 

七、Redis的基本数据结构

 

    1)字符串 

            key - value

    2)哈希

            key - {field: value, field: value....}

    3)链表

            key - value1,value2,value3....

            底层数据结构:双向链表

    4)集合

            key - [value3,value5,value1,value2....]

            底层数据结构:哈希表

    5)有序集合

            key - [(score,value1), (score,value2), (score,value3).....]

            底层数据结构:跳跃表

    6)基数

 

    redis中文网: https://www.redis.net.cn/

 

    

 

    注意:redisTemplate根据不同的数据结构,将相关的操作方法封装到不同的对象当中。但是有些命令是通用的,就直接通过redisTemplate调用就可以了。比如删除一个key

 

八、redis的发布和订阅 - (RedisMQ)

 

    RedisMQ和传统的MQ组件有什么区别?

    

    RedisMQ:轻量级、消息实时性较好,但是消息可靠性较低,而且消息不能持久化,所以redis适合那种消息实时性要求较高但是可靠性要求较低的场景

    

    传统的MQ:专业级、消息实时性相对较低,但是通常都有消息的可靠性保证机制,而且消息也能够持久化,并且消息的存储量级可以非常大。

 

 

九、超时命令

 

    什么是超时命令?

    超时命令就是用来设置一个key的过期时间

 

    为什么需要超时时间?

    redis的数据是存放在内存中的,通常数据库中的数据不可能完全的同步到redis中,提升系统性能。所以在实际开发过程中,通常需要redis中保留更多的热点数据,但是如何保证redis中尽可能的存储热点数据?就需要通过key的超时命令实现。对所有的key都设置一个超时命令,如果是热门数据,这个key过期后,自然会被立刻重建回缓存,但是冷门数据就会自动的删除掉,节省redis的内存空间。

 

    注意:在很多公司都有一定的开发规范,通常都要求设置缓存key的时候,跟上超时时间

 

    超时的相关命令:

    ttl:查看当前key的超时时间

        -1 - 表示永生(没有超时时间)

        -2 - 表示当前key已经超时或者不存在

        正整数 - 剩余的存活时间

 

    expire:设置超时时间

    persist:移除key的超时时间

 

    SpringBoot如何设置过期时间:

    

 

    面试题:redis中一个key过期之后,是否立刻从内存中移除?

        no - 不是,因为如果要做到实时移除,会对redis的性能损耗巨大。

 

        redis在3种情况下,会移除过期的key-value:

        1)当用用户尝试获取一个过期的key时,会立刻从内存中移除这个key

        2)redis自带一个定时器,定期扫描部分内存,移除其中过期的key

        3)当redis的内存已经满了后,根据内存的淘汰策略可能淘汰掉某些过期的key(有可能永生的key也会被移除)

 

十、Lua脚本

 

    1)redis的线程模型(单线程模型/多线程模型):

 

        多线程模型(tomcat):

        

 

        单线程模型(redis):

        

 

 

        为什么redis会采用单线程模型?(单线程模型和多线程模型哪种更好?)

            多线程模型通常用于处理请求较慢的服务,比如tomcat。如果tomcat设计成单线程模型的问题,在于多个用户同时发送请求时,有些用户的请求可能会涉及数据库的访问、网络的访问等等比较耗时的操作,那么tomcat的单线程就会阻塞到这些耗时请求之上,这些请求没有返回结果时,tomcat服务的cpu就会处于空闲的状态,一直到这些请求返回结果之后,tomcat才能继续处理其他的请求。因此单线程模型不适合tomcat服务,会极大的浪费cpu的资源。

 

            单线程模型通常适合处理请求极快的服务,比如redis。因为redis不会有耗时的操作(比如访问数据库,访问网络的操作),而且redis是直接操作内存的,所以每个请求的操作速度都会非常的快。如果采用多线程模型,反而还需要进行线程间的切换,带来额外的服务器性能损耗。

 

        既然redis是单线程模型,能不能认为redis的所有操作都是线程安全的?

            NO,虽然redis是单线程模型,但是不能表示redis是线程安全的。因为用户的多个命令之间有可能会夹杂着其他用户的命令,从而导致最后的数据结果不一致。但是redis提供了一种命令原子性的特性 - Lua脚本。redis中执行lua脚本一定是原子操作,要么都不执行,要么都执行,在执行lua脚本的过程中是不会再去直接其他客户端命令的。

 

 

    2)lua脚本的语法:

        .....

    

    3)redis如何操作lua脚本:

 

        语法:eval  "lua脚本"  number  [key1 key2....]  [arg1 arg2.....]

            number:表示lua脚本中,key的数量,如果没有key,则设置为0

            [key1 key2....]:表示对应lua脚本中key的变量值

            [arg1 arg2.....]:表示对应lua脚本中非key的变量值

 

        案例:

            eval "return 'Hello'" 0

            eval "redis.call('set', 'name', 'xiaoming')" 0

            eval "return redis.call('get', 'name')" 0

            eval "redis.call('set', KEYS[1], ARGV[1])" 1 age 18 - 带变量

            

        lua脚本的缓存:

            缓存脚本:script load "return redis.call('get', KEYS[1])"

                返回值:"4e6d8fc8bb01276962cce5371fa795a7763657ae"

            

            执行缓存的脚本:evalsha "4e6d8fc8bb01276962cce5371fa795a7763657ae" 1 name

 

    4)SpringBoot如何操作lua脚本

        

 

 

 

十一、Redis作为缓存服务器的使用+redis的分布式锁

 

    

十二、Spring提供的缓存注解

    

    1)添加相关依赖

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-cache</artifactId>

        </dependency>

 

    2)配置启动类

        

 

    3)使用注解实现数据缓存

        @Cacheable:当前执行一个标记了该注解的方法,会先去缓存服务器(redis)中获取缓存的数据,如果没有找到,则调用目标方法,如果找到了相关数据,则不会再调用目标方法。如果调用了目标方法,会自动的将方法的返回值重建到缓存服务器中。

        @CacheEvict:调用当前方法后,直接删除指定缓存

        @CachePut:该注解会将目标方法的返回值添加进缓存中,通常用户添加方法

        @Caching:支持在一个方法上添加多个重复注解

 

    4)配置application.yml设置超时时间

        

 

    注意:spring提供的cache缓存,如果检测到redis的相关依赖,会自动的将缓存数据放入redis中

 

 

十三、redis的持久化

 

    redis持久化的方式:

    

        1)快照 - rdb(默认行为)

            快照是通过记录当前内存一瞬间的数据结构的方式

 

            相关命令:

                save - redis就会执行一次快照操作,这个命令会在当前线程进行快照,在快照时,redis就不能写入数据

                bgsave - redis会执行一次后台快照,前台仍然会接收写的命令

 

            相关配置:

                save 900 1

                save 300 10

                save 60 10000 

                    - 配置redis的快照频率,900s之内有1个数据发生变化就快照一次,一次类推

                

                stop-writes-on-bgsave-error yes 

                    - 配置bgsave如果出错前台是否停止写入,默认yes

 

                dbfilename dump.rdb

                    - 配置快照的文件名

 

                dir ./

                    - 配置快照的存放路径

 

        2)只追加文件 - aof

            只追加文件会记录所有的写命令到一个文件中,当redis重启之后,重新直接记录的所有写命令,从而恢复数据

 

            相关配置:

                appendonly no

                    - 是否开启只追加模式,默认关闭

 

                appendfilename "appendonly.aof"

                    - 配置只追加数据的文件名称

    

                # appendfsync always

                appendfsync everysec

                # appendfsync no

                    - 配置只追加文件的频率

                

                auto-aof-rewrite-percentage 100

                auto-aof-rewrite-min-size 64mb

                    - 配置只追加文件什么时候重新创建一个新的文件记录命令

            

        什么时候选择快照,什么时候选择只追加文件?

            快照特点:恢复速度很快,但是数据相对来说安全性不高

            aof特点:文件可能很大,并且恢复缓慢,但是数据相对比较安全,aof最多只会丢失1秒之内的数据

 

            如果redis只作为缓存服务器使用,那么快照和aof都可以关闭。如果希望数据绝对安全,最好把两个持久化方式都开启,redis会按按照aof恢复数据,再按照快照恢复数据。通常来说,只要开启快照就足够了。

 

        如何对aof文件进行优化?

            优化aof的命令:bgrewriteaof  

            注意:redis2.4之后,服务会定期自动的执行该命令优化aof文件

 

 

十四、redis内存回收策略

 

        什么是内存回收策略?

            内存回收策略是指,如果redis内存已经满了,会按照哪种方式对待新的写入

 

        相关配置:

            maxmemory-policy noeviction

                - 配置内存淘汰策略

 

            maxmemory-samples 5 

                - 指定淘汰时抽取的样本数量

 

        可选值:

            volatile-lru(推荐) -> 从所有设置了超时时间的key中,找到最近最少被使用的key淘汰

            allkeys-lru -> 从所有的key中,找到最近最少被使用的key淘汰

            volatile-random -> 从所有设置了超时时间的key中,随机找到key淘汰

            allkeys-random -> 从所有的key中,随机找到key淘汰

            volatile-ttl(推荐) -> 从所有设置了超时时间的key中,找到存活时间最短的key淘汰

            noeviction(默认值) -> 如果内存已经满了,redis变成只读模式

 

            volatile - 会从所有设置了超时时间的key中淘汰(有可能这个key没有超时)

            allkeys - 会从所有key中淘汰(永生的key也有可能被淘汰)

            lru - 最近最少被使用的策略

            random - 随机

            ttl - 存活时间最短

 

        注意:在redis中,ttl和lru都是近似算法,不是绝对算法

 

十五、redis的集群模式 - 读写分离(了解)

 

        有状态服务:每个服务本身有自己独立的数据空间,比如redis、mysql、zookeeper.....

        无状态服务:每个服务本身没有独立的数据空间,比如tomcat

 

        无状态服务可以通过单纯的横向拓展就能实现集群的效果

        有状态服务不能单纯的横向拓展实现集群,不同的服务有不同的实现方式

 

        读写分离:

        

 

        哨兵模式:

        

 

 

        搭建主从复制:

 

            1) 准备3个虚拟机:

                192.168.227.142 - master

                192.168.227.143 - slave1

                192.168.227.144 - slave2

 

            2)分别启动redis

                

            3)配置slave

                

                重启slave

 

        搭建哨兵模式:

            

            1)从redis的路径下,将哨兵的配置文件拷贝到src中

 

            2)配置sentinal.conf配置文件

                

 

            3)开放26379的端口(哨兵的端口,因为哨兵之间会两两监控,所以需要开放端口)

 

            4)依次启动哨兵    

                ./redis-sentinel sentinel.conf

 

 

        springboot中如何配置哨兵的读写分离:

            

 

 

        分片模式:

            

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值