为什么会出现NOSQL
1.关系型数据库无法满足并发数据的读写以及海量数据的存储
NOSQL的四大分类
1.键值对存储
比如redis,优点是快速查询,缺点是存储的数据缺少结构化
2.列存储
优点是查询快、拓展强,缺点是功能相对局限
文档数据库
MobgoDB,数据库结构要求不严格,查询性能不高,缺少统一查询语法
图形数据库
需要对图形做计算,不容易做分布式集群方案
NOSQL的特点
1.易拓展
2.数据模型灵活,无需对存储的数据建立字段
redis的五种数据结构
1.字符串(string)
Redis 最基本的数据类型,数据已二进制形式存储,可以包含任何数据。比如jpg图片或者序列化的对象。string 类型的值最大能存储 512MB。
2.字符串列表(list)
底层基于双向链表实现,增删快
适用场景:最新消息排行,消息队列
3.字符串集合(set)
基于哈希表,所有元素不重复
4.有序字符串集合(sorted set)
将set中的元素添加权重参数score,元素按照score有序排列
适用场景:排行榜、带权重的消息队列
5.哈希(hash)
键值对集合,类似java中的map特别适合存储对象,key还是string类型,但是value成了一个map
redis中KEY的注意事项
1.1.key不要太长,尽量不要超过1024字节,这不仅消耗内存,而且会降低查找的效率;
1.2.key也不要太短,太短的话,key的可读性会降低;
1.3.在一个项目中,key最好使用统一的命名模式,例如user:10000:passwd。
redis的持久化方式
1.RDB (redis database)
在指定的时间间隔内将内存中的数据集快照(Snapshot快照)以二进制的方式保存到磁盘中,恢复时将快照文件读到内存中。
redis会单独创建一个子进程来进行持久化,先将数据写入到临时文件中,待持久化过程结束,再用这个临时文件替换上次持久化好的文件,整个过程中子进程不进行任何IO操作,确保了极高的性能
优点:节省磁盘空间、恢复速度快
缺点:在指定时间间隔内进行备份,有可能数据丢失
2.AOF(append of file)
以日志的形式来记录每一个写操作(不记录读操作),将redis执行的所有写操作记录下来追加到文件中(文件不允许修改),redis在重启的时候会读取该文件的所有写操作并执行达到恢复数据的目的
优点:丢失数据概率低、可通过该日志文件处理误操作
缺点:占用的磁盘空间大、恢复备份速度慢、同步记录写操作有一定的性能问题
缓存雪崩
1.缓存雪崩是什么?
如果所有的Key失效时间都是12小时,中午12点刷新的,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,它会报一下警,真实情况可能DBA都没反应过来就直接挂了。此时,如果没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。
2.处理方法
1、在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效。
setRedis(Key,value,time + Math.random() * 10000);
2、设置热点数据永远不过期
3、如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题
缓存穿透
1.什么是缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,我们数据库的 id 都是1开始自增上去的,如发起为id值为 -1 的数据或 id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。
2.解决方法
1.在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等。
2.布隆过滤器,利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。
缓存击穿
1.什么是缓存击穿
缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。
2.解决方法
设置热点数据永远不过期。或者加上互斥锁