Redis(REmote DIctionary Server)-简介、特点、优势、安装、数据类型、常用命令、API操作、SpringBoot集成Redis、持久化策略、缓存穿透、击穿、雪崩

1. Redis的简介

  • Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理
  • 它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型
  • 内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。
  • 简言之,Redis是一种面向“键/值”对数据类型内存数据库,可以满足我们对海量数据的快速读写需求。

2 Redis的特点

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
  • Redis不仅仅支持简单的k-v类型的数据,同时还提供list,set,zset,hash等数据结构的存储
  • Redis支持数据的备份,即master-slave主从模式的数据备份

3 Redis的优势

  • 性能极高-Redis读的速度为11W/s,写的速度为8.1w/s。
  • 丰富的数据类型(String,Lists,Hashes,Sets及OrderedSets)。
  • 原子性-Redis所有的操作都是原子性的,同时Redis还支持对几个操作进行合并后的原子性执行。
  • 丰富的特性-支持publish/subscribe,通知,key过期等特性。

4 常用的NoSql数据库

  • hbase:存储海量的数据(数十亿行,百万列)
  • redis:基于内存的NoSql数据库,一般使用Redis做缓存或者队列
  • mogodb:在结构化数据比较简单的情况下,可以使用mogodb代替mysql,作为一个高性能的数据库

5 Redis的安装

5.1 Redis单机版的安装

  1. 准备源码安装包 redis-5.0.10.tar.gz
  2. 安装GCC编译器、lsof(lists openfiles)列出打开文件
  3. 解压 tar -zxvf redis-5.0.10.tar.gz -C /opt
  4. 重命名 cd /opt mv redis-5.0.10/ redis
  5. 编译安装源码 cd redis/ make && make install
  6. 添加环境变量 vim /etc/profile
export REDIS_HOME=/opt/redis
export PATH=$PATH:$REDIS_HOME/src
  1. 重新执行刚修改的初始化文件,使之立即生效 source /etc/profile
  2. 修改redis.conf的配置项 cd src vim redis.conf
bind 0.0.0.0 (默认是127.0.0.1,这是本地回环地址,只能本地应用程序之间进行通信)
daemonize yes(后台运行)
logfile /opt/redis/logs/redis.log(日志文件,目录必须存在)
  1. 新建日志文件目录 mkdir -p /opt/redis/logs
  2. 启动Redis-Server redis-server /opt/redis/redis.conf
  3. 启动redis客户端redis-cli -h 10.10.10.21 -p 6279

5.2 Redis的集群安装

node1 master
node2 slave
node3 slave
  • 把前面安装好的单机版的redis拷贝到node2 node3
  • 再给节点(node2 node3) redis.conf 末尾追加slaveof node1 6379

ps:注意启动集群时尽量先启动主节点再启动从节点

6 Redis中配置的查看

Redis的配置文件位于Redis的安装目录之下,文件名为redis.conf。可以通过config命令来查看或设置配置项

config get confName: 获取配置的值
config set confName confVal: 设置配置的值

使用config配置的模式,只是在当前的会话中有效,如果redis重新启动则失效了

7 Redis中的数据类型

  • string(字符串)
  • hash(哈希)
  • list(列表)
  • set(集合)
  • zset(sorted set)有序的集合

8 数据类型之String(字符串)

  • string是redis中最基本的数据类型
  • 一个key对应一个value
  • string类型的value是基于二进制存储的,所以完全可以存储图片和影音等二进制数据
  • string类型的value大小最大512mb

  • 存储数据: set key value
  • 一次性存储多个数据 mset key value [key value...]
  • 读取数据: get key
  • 删除redis中的key说对应的value: del key
  • 计数器操作
set mage 20 #添加一个value
incr mage #自增1
decr mage #自减1
incrby mage 100 #自增指定的值
decrby mage 55 #自减指定的值
  • 添加具有过期时间的键值对 setex key seconds value
  • 查看过期时间 ttl key
  • 给value追加字符串 append key value

9 数据类型之Hash(哈希)

  • Redis hash 是一个键值对集合。Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象object

  • 存储一个数据: hset key field value
  • 获取数据: hget key field
  • 设置多个数据: hmset key field value[key field value...]
  • 获取多个数据: hmget key value[value...]
  • 删除hash中的多个个键值对:hdel key value[value...]
  • 删除redis中的key说对应的value: del key [key...]
  • 获取指定的key的全部键值对: HGETALL key
  • 获取指定的key对应的元素的个数: HLEN key

10 数据类型之List(列表)

  • Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

  • 首部添加数据: lpush key value[value...]
  • 尾部添加元素: rpush key value[value...]
  • 查看数据: lrange key start stop
  • 首部移除元素: LPOP key
  • 尾部移除元素: RPOP key

列表最多可存储 2^32-1元素 (4294967295, 每个列表可存储40多亿)

11 数据类型之Set(集合)

12 数据类型之ZSet(有序集合)

13 Redis中的常用命令

13.1 键值对相关

keys * 取出当前所有的key
exists name 查看redis是否有name这个key
del name 删除key name
expire confirm 100 设置confirm这个key100秒过期
ttl confirm 获取confirm 这个key的有效时长
persist confirm 移除confirm这个key的过期时间
select 0 (在redis中总共有16个数据库,默认是0号数据库)
move confirm 1 将当前数据库中的key移动到其他的数据库中
randomkey 随机返回数据库里面的一个key
rename key2 key3 重命名key2 为key3
type key2 返回key的数据类型
SHUTDOWN 关闭redis数据库

13.2 服务器相关

select 0~15 编号的数据库
quit /exit 退出客户端
dbsize 返回当前数据库中所有key的数量
info 返回redis的相关信息
flushdb 删除当前选择数据库中的所有key
flushall 删除所有数据库中的数据

14. Redis中的API操作

  • pom依赖

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
    
  • 常用操作

    package com.uplooking.bigdata.redis;
    
    import org.junit.Test;
    import redis.clients.jedis.Jedis;
    
    public class RedisTest {
        @Test
        public void testString() {
            //创建Jedis
            Jedis jedis = new Jedis("uplooking03");
            jedis.select(0);
            jedis.set("name", "value");
            System.out.println(jedis.get("name"));
        }
    
    
        @Test
        public void testHash() {
            //创建Jedis
            Jedis jedis = new Jedis("uplooking03");
            jedis.select(0);
            jedis.hset("info", "name", "admin");
            jedis.hset("info", "age", 12 + "");
            System.out.println(jedis.hget("info", "name"));
        }
    
    
        @Test
        public void testList() {
            //创建Jedis
            Jedis jedis = new Jedis("uplooking03");
            jedis.select(0);
            jedis.rpush("loves", "java", "c++", "python");
            jedis.lpop("loves");
            System.out.println(jedis.lrange("loves", 0, 10000));
            System.out.println(jedis.rpop("loves"));
            System.out.println(jedis.lrange("loves", 0, 10000));
        }
    }
    
    

15. Redis设置密码

 requirepass root  #配置密码为root
登录redis:
    redis-cli -h node1
    auth root

16. Redis可视化工具

RedisDesktopManager

17.SpringBoot集成Redis

  • 引入依赖

     <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.3.RELEASE</version>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
        </dependencies>
    </project>
    
  • 注入redisTemplate

    package com.up;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    
    @SpringBootApplication
    public class Application implements CommandLineRunner {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class);
        }
    
        @Autowired
        private StringRedisTemplate redisTemplate;
    
        @Override
        public void run(String... args) throws Exception {
    //        redisTemplate.opsForValue().set("name123", "xiaohua");
    //        redisTemplate.opsForList().leftPush("loves", "java");
            redisTemplate.opsForHash().put("score", "java", String.valueOf(30));
        }
    }
    

18. Redis的持久化策略

reids是一个key-value存储系统,为了保证效率,缓存在内存中,但是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,以保证数据的持久化;

所以:redis是一个支持持久化的内存数据库,可以将内存中的数据同步到磁盘保证持久化;

Redis的持久化策略:2种

rdb: rdb数据快照形式,是直接把内存中的数据保存到一个dump文件中,定时保存;
aof:把所有的对redis的服务器进行'写操作'的命令都存到一个文件里,命令的集合

默认redis只开启的是rdb策略,我们可以手动开启aof策略,当开启aof策略时,服务器启动时优先使用aof策略;

18.1 rdb策略

原理: 当redis需要做持久化时,redis会fork一个子进程;子进程将数据写到磁盘上一个临时RDB文件中;当子进程完成写临时文件后,将原来的RDB替换掉,这样的好处就是可以copy-on-write(写时复制技术)

redis.conf配置:

save 900 1 
save 300 10
save 60 10000

默认是如上配置:

900秒之内,如果超过1个key被修改,则发起快照保存;
300秒内,如果超过10个key被修改,则发起快照保存
1分钟之内,如果1万个key被修改,则发起快照保存

注意:以上的配置只要触发任意一个操作都会执行备份rdb快照的操作 'BGSAVE'

这种方式不能完全保证数据持久化,因为是定时保存,所以当redis服务down掉,

就会丢失一部分数据,而且数据量大,写操作多的情况下,会引起大量的磁盘IO操

作,会影响性能;

所以,如果这两种方式同时开启,如果对数据进行恢复,不应该用rdb持久化方式对数据库进行恢复

18.2 AOF策略

AOF持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集,它可以实现每次操作都持久化;

AOF文件中的命令全部以redis协议的格式来保存,新命令会被追加到文件的末尾。 redis还可以在后台对AOF文件进行重写(rewrite),使得AOF文件的体积不会超出保存数据集状态所需的实际大小。redis还可以同时使用AOF持久化和RDB持久化。在这种情况下,当redis重启时,它会优先使用AOF文件来还原数据集, 因为AOF文件保存的数据集通常比RDB文件所保存的数据集更完整。也可以关闭持久化功能,让数据只在服务器运行时存在。

配置方式:启动aof持久化的方式

appendonly yes 

AOF文件刷新的方式,有三种

appendfsync everysec

appendfsync always:每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用
appendfsync everysec:每秒钟都调用fsync刷新到AOF文件,很快,但可能会丢失一秒以内的数据;(推荐)
appendfsync no:依靠OS进行刷新(一般30s左右一次刷新),redis不主动刷新AOF,但安全性就差。
默认并推荐每秒刷新,这样在速度和安全上都做到了兼顾。

18.3 redis持久化策略优先级

AOF优先于RDB
RDB性能优于AOF,因为里面没有重复
Redis一次性将数据加载到内存中,一次性预热

18.4 生产环境的备份

为以防万一(机器坏掉或磁盘坏掉),最好定期把使用filesnapshotting 或 Append-only 生成的*rdb *.aof文件备份到远程机器上,然后可以用crontab定时(比如每半小时)scp一次。如果没有使用redis的主从功能 ,半小时备份一次应该是可以了;并且如果应用数据量不大的话,可以单机部署,做主从有点浪费。具体还是要根据应用而定。

18.5 生产环境恢复数据

1)确保redis是未启动状态

2)把备份的rdb或者aof文件放入redis的安装路径 /opt/redis

3)启动redis,会主动加载rdb或者aof备份文件,加载哪个文件取决于是否开启aof,没开启默认加载rdb,开启了优先加载aof;


19. 缓存穿透是什么?

  • 缓存穿透指查询不存在的数据,缓存层和存储层都不会命中,导致不存在的数据每次请求都要到存储层查询,可能会使后端负载增大。

  • 解决:
    ① 缓存空对象,如果一个查询返回结果为 null,仍然缓存,为其设置很短的过期时间。
    ② 布隆过滤器,将所有可能存在的数据映射到一个足够大的 Bitmap 中,在用户发起请求时首先经过布隆过滤器的拦截,一个一定不存在的数据会被拦截。

20 缓存击穿是什么?

对于热数据的访问量非常大,在其缓存失效的瞬间,大量请求直达存储层,导致服务崩溃。

解决:
① 加锁互斥,当一个线程访问后,缓存数据会被重建。
② 永不过期,为热点数据不设置过期时间。

21 缓存雪崩是什么?

如果缓存层因为某些问题不能提供服务,所有请求都会到达存储层,对数据库造成巨大压力。

解决:
① 保证高可用性,使用集群。
② 依赖隔离组件为后端限流并降级,降级机制在高并发系统中使用普遍,例如在推荐服务中,如果个性化推荐服务不可用,可以降级补充热点数据,避免前端页面空白。
③ 构建多级缓存,增加本地缓存,降低请求直达存储层概率。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值