3. redis知识点

Redis 基础知识点

什么是Redis

Redis是一个基于内存的高性能key-value 非关系型数据库

Redis 支持得数据类型

  • String(字符串) :该类型是redis 最基础的数据结构key/value 结构, 它是数据安全的, 最大只能存储521MB. 其他几种数据类型都是在该类型的基础上创建的. 适用于缓存, 计数和共享session

  • Hash(哈希): 该类型的value 本身又是一种key/value结构, 适用于存储对象信息

  • List(列表): 它是一个字符串列表, 可以在开头或结尾插入操作数据, 适用于消息队列等

  • Set(无序集合):存储的是一个不重复的集合, 适用于拥有共同点的场合下

  • Zset(有序集合): 和set相同只是可以对集合中的元素进行排序, 适用于排行榜等

Reids应用场景

  1. 会话缓存(session cache)

  2. 全页缓存(FPC)

  3. 队列

  4. 排行榜/计数器

  5. 发布/订阅

Redis 有哪些好处

  1. 速度快.因为数据存在内存中,类似于hashmap, hashmap的优势就是查找和操作的时间复杂度都是O(1)

  2. 支持丰富的数据类型: string,list,set,sorted,hash

  3. 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部都不执行.

  4. 丰富的特性: 可用于缓存,消息,按key设置过期时间,过期后将会自动删除.

Redis持久化方式机制

RDB持久化(内存快照)

该机制是指在指定得时间间隔内将内存中的数据集快照写入磁盘

优点:

  1. 只有一份rdb文件, 可随时备份

  2. 比AOP文件小,加载效率高

  3. 只提供fork子进程, 不阻塞主进程, io操作比较少

AOF(日志文件)持久化

该机制将日志的形式记录服务器所处理的每一个写操作,在redis服务器启动之初会读取该文件来重新构建数据库, 以保证启动后数据库中的数据是完整的

优点:

  1. 每次改动同步数据安全性好

  2. APPEND(附加)方式追加日志,不会对旧日志文件产生影响

无持久化

我们可以通过配置的方法禁止redis服务器的持久化功能,这样我们就可以将redis视为一个功能加强版的memcached了

redis 击穿,穿透,雪崩问题

redis击穿是什么

缓存击穿是指一个key非常热点,在不断地扛着大并发,大并发集中对这一个点进行访问,当这个key失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,造成缓存击穿

解决方法:

1)通过synchronized+双重检查机制:某个key只让一个线程查询,阻塞其它线程

在同步块中,继续判断检查,保证不存在,才去查DB。

代码示例:

private static volaite Object lockHelp=new Object();
public String getValue(String key){
    String value=redis.get(key,String.class);
    if(value=="null"||value==null|| StringUtils.isBlank(value){
        synchronized(lockHelp){
            value=redis.get(key,String.class);
            if(value=="null"||value==null||StringUtils.isBlank(value){

                value=db.query(key);
                redis.set(key,value,1000);
            }
        }
    }
    return value;
}

缺点: 会阻塞其它线程

2)设置value(key)永不过期

这种方式可以说是最可靠的,最安全的但是占空间,内存消耗大,并且不能保持数据最新 这个需要根据具体的业务逻辑来做;个人觉得如果要保持数据最新不放这么试试,仅供参考:起个定时任务或者利用TimerTask 做定时,每个一段时间多这些值进行数据库查询更新一次缓存,当然前提时不会给数据库造成压力过大(这个很重要)

  1. 使用互斥锁(mutex key)

业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。

SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。在redis2.6.1之前版本未实现setnx的过期时间,所以这里给出两种版本代码参考:

public String get(key) {
    String value = redis.get(key);
    if (value == null) { //代表缓存值过期
        //设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
        if (redis.setnx(key_mutex, 1, 3 * 60) == 1) {  //代表设置成功
            value = db.get(key);
            redis.set(key, value, expire_secs);
            redis.del(key_mutex);
            return value;
        } else {  //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
            sleep(10);
            get(key);  //重试
        }
    } else {
        return value;
    }
}

缺点:

  1. 代码复杂度增大

  2. 存在死锁的风险

  3. 存在线程池阻塞的风险

原文链接:https://blog.csdn.net/qq_27409289/article/details/85885121

Redis的穿透

缓存穿透是指缓存和数据库中都没有数据,而用户不断发起请求,这时的用户很有可能是攻击者,攻击导致数据库压力过大,严重击垮数据库。

解决方法:

1)接口层增加校验,对用户请求的参数做校验,不合法的参数直接return。

  1. 使用布隆过滤器: 热点数据等场景(具体看使用场景)

缓存雪崩

雪崩指的是多个key查询并且出现高并发,缓存中失效或者查不到,然后都去数据库查询,从而导致db压力突然飙升,从而崩溃。

出现原因:

​ 1. key同时失效

​ 2. redis本身崩溃了

解决方法:

1)搭建redis集群

  1. 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。(跟击穿的第一个方案类似,但是这样是避免不了其它key去查数据库,只能减少查询的次数)

  2. 可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存

4)不同的key,设置不同的过期时间,具体值可以根据业务决定,让缓存失效的时间点尽量均匀

5)做二级缓存,或者双缓存策略。A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。(这种方式复杂点)

  1. 设置时间永不过期

原文链接:https://blog.csdn.net/qq_27409289/article/details/85885121

Redis 性能优化

1尽量使用短的key

当然在精简的同时,不要为了key的“见名知意”。对于value有些也可精简,比如性别使用0、1。

2、避免使用keys*

keys *, 这个命令是阻塞的,即操作执行期间,其它任何命令在你的实例中都无法执行。当redis中key数据量小时到无所谓,数据量大就很糟糕了。所以我们应该避免去使用这个命令。可以去使用SCAN,来代替。

3、在存到Redis之前先把你的数据压缩下

redis为每种数据类型都提供了两种内部编码方式,在不同的情况下redis会自动调整合适的编码方式。

4、设置key有效期

我们应该尽可能的利用key有效期。比如一些临时数据(短信校验码),过了有效期Redis就会自动为你清除!

5、尽可能地使用hashes哈希存储

6、当业务场景不需要数据持久化时,关闭所有的持久化方式可以获得最佳的性能;数据持久化时需要在持久化和延迟/性能之间做相应的权衡.

7、想要一次添加多条数据的时候可以使用管道

原文链接:https://blog.csdn.net/weixin_44098139/article/details/88972180

Redis性能调优建议

1. Master不做AOF或RDB持久化,Slave做AOF持久化,建议同时做RDB持久化
2. 所有Master全部增加Slave
3. Master挂载Slave不超过2个,采用M-S-S方式挂载(链式挂载)。若想保证高可用,即主从切换,可采用Keepalived机制.

原文参考: https://blog.csdn.net/hexieshangwang/article/details/47253949?depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-3&utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-3

Redis和 mongoDB有什么区别

MongoDB 更类似 MySQL,支持字段索引、游标操作,其优势在于查询功能比较强大,擅长查询 JSON 数据,能存储海量数据,但是不支持事务.

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,支持多种类型的数据结构,可用作数据库,高速缓存和消息队列代理。

1、内存管理机制

Redis 数据全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的 LRU 算法删除数据。

MongoDB 数据存在内存,由 linux系统 mmap 实现,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。

2、支持的数据结构

Redis 支持的数据结构丰富,包括string、hash、set、lis、zset等。

MongoDB数据结构比较单一,但是支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。

3、数据量和性能:

当物理内存够用的时候,redis>mongodb>mysql

当物理内存不够用的时候,redis和mongodb都会使用虚拟内存。

实际上如果redis要开始虚拟内存,那很明显要么加内存条,要么你换个数据库了。

但是,mongodb不一样,只要,业务上能保证,冷热数据的读写比,使得热数据在物理内存中,mmap的交换较少。

mongodb还是能够保证性能。

4、性能

mongodb依赖内存,TPS(系统吞吐量)较高;Redis依赖内存,TPS非常高。性能上Redis优于MongoDB。

5、可靠性

mongodb从1.8版本后,采用binlog方式(MySQL同样采用该方式)支持持久化,增加可靠性;

Redis依赖快照进行持久化;AOF增强可靠性;增强可靠性的同时,影响访问性能。

可靠性上MongoDB优于Redis。

6、数据分析

mongodb内置数据分析功能(mapreduce);而****Redis****不支持。

7、事务支持情况

Redis 事务支持比较弱,只能保证事务中的每个操作连续执行;mongodb不支持事务。

8、集群

MongoDB 集群技术比较成熟,Redis从3.0开始支持集群。

原文参考: https://www.cnblogs.com/fengqiang626/p/11465401.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值