目录
nosql概述
非关系型数据库,不保证数据acid特性,为了应对超大规模和高并发系统里多重数据种类带来的挑战,例如,Redis,HBASE,elacticsearch,mongodb
使用场景,1.数据模型比较简单
2.灵活性更强的数据库
3.对数据库性能要求高
4.不需要高度的数据一致性
5.对于给定key,更加方便对应复杂的映射
类型分类,键值对型数据库,用于内存缓存,处理大量数据高负载访问,代表产品,Redis
列存储数据库,用于分布式数据存储和管理,扩展性强,代表产品,HBASE
文档数据库,用于管理半结构化数据或面向文档数据,MongoDB,elasticsearch
图形数据库,用于复杂,互相连接但又低结构化的图形结构场景,用来构建关系图谱。neo4j,infogrid
Redis,对数据的读写要求高,规模不大,不需要长期存储
MongoDB,数据规模大,读性能要求高,表结构需要经常变更,支持聚合查询
elasticsearch,构造一个搜索引擎,数据具有分析价值
HBASE,存储海量数据,不能预估数据规模将来增长多少
Redis
基于内存实现的键值对数据结构的nosql数据库
内存存储,所有数据存储在内存里,数据io性能比较高,提供了持久化策略避免内存数据丢失问题。这样可以作为应用程序与数据库之间的缓存组件。
使用键值对存储数据,
nosql是一种非关系型数据库,相对于传统数据库,更多考虑到扩展性,性能,大数据存储,弥补关系型数据库的短板,不存在表之间的关联查询问题。
Redis提供了主从复制加哨兵以集体方式实现高可用。在集体里面通过hash槽的方式实现数据分片,提高性能。
数据类型,string,Map,set,zset,list
单线程,Redis对外提供的键值对存储服务,网络io和数据读写是由单个线程完成,持久化,异步删除,集群数据同步是由额外的线程执行。
Redis为什么效率高
1.基于内存操作,数据存储在内存里,类似hashmap的数据结构,对数据操作简单。
2.降低了CPU消耗,采用单线程,避免不必要的上下文切换和加锁和释放锁的操作。
3.采用了高效的非阻塞io。Redis采用epoll作为io多路复用技术的实现,加上事件处理模型,将epoll里的连接,读写,关闭都转换为了事件,提高了io效率,使得Redis在网络io操作里能处理大量用户的请求,实现了高吞吐量。
线程安全问题,Redis6.0版本支持多线程是针对网络io的多线程支持,Redis命令操作是线程安全的。
之前版本Redis处理客户端请求时,socket连接,读取,解析,执行,写回命令都是由一个线程来处理,这种方式在用户请求比较多的情况下,网络处理效率低。Redis6.0针对网络io的处理方式改成多线程,解决了网络io的处理效率问题,
Redis指令执行不使用多线程的原因,
1.内存io操作不存在性能瓶颈,Redis在数据结构上做了优化。
2.如果指令执行使用多线程,为了解决线程安全问题,需要对数据操作加锁,增加了复杂度,影响性能。
缓存雪崩
存储在缓存里的大量数据在同一时间全部过期,原本缓存组件处理数据流量全部到达数据库,导致数据库压力增加,最后造成数据库崩溃的现象。
导致缓存雪崩的原因:
1.缓存中间件宕机,通过缓存中间件集体避免。
2.缓存里大部分的key都设置相同的过期时间,导致同一时刻全部过期,可以在失效时间上加上1到5min的随机值。
缓存穿透
短时间内有大量不存在的key请求应用程序,这些key在缓存里面找不到,这样这些请求全部到了数据库,给数据造成压力,这可能是一种对缓存的攻击行为,在正常的业务里面,即使出现了这样的情况,由于缓存不断的预热,影响不会很大。而攻击行为具备时间上的持续性,只有key确实不存在于数据库的情况下,才能达到这个目的。
解决方法,
1.把无效的key保存到Redis里面,设置一个特殊的值null,下次访问的时候不需要查询数据库。
2.使用布隆过滤器,在系统启动的时候把目标数据全部缓存的布隆过滤器里,当攻击者使用不存在的key请求的时候,先到布隆过滤器里面查询,如果查询不到,那么意味着这个key在数据库里也不存在,布隆过滤器采用bitmap存储数据,占用内存空间少。
持久化
Redis是一个基于键值对结构的内存数据库,为了避免故障导致数据丢失问题,Redis提供了rdb和AOF2种持久化机制。
RDB,快照的方式实现,把内存里面的数据快照写入磁盘,以二进制的压缩文件进行存储。
触发方式,
1.执行bgsave命令触发异步快照,执行save命令执行同步快照,同步快照会阻塞客户端指令。
2.根据配置文件里配置自动触发bgsave.
3.主从复制时触发。
AOF,把Redis执行事务命令进行追加存储。客户端执行一个数据变更操作,Redis把这个命令追加到AOF缓冲区末尾,再把缓冲区的数据写入磁盘的AOF文件,
AOF指令追加的方式会造成AOF文件过大,带来io性能问题,所以Redis提供了AOF重写机制,
AOF重写机制,当AOF文件大小到达某个阈值的时候,就会把相同的指令进行压缩。
如果AOF文件里面存储了某个key的多次变更记录,但是在数据最终恢复的时候,只需要执行最新的指令操作即可。
具体步骤,1.根据当前Redis内存里面的数据,重新构建一个新的AOF文件
2.读取当前Redis里面的数据,写入新的文件。
3.重写完成后用新的文件覆盖旧的文件。
当AOF在重写过程里需要读取当前内存里所有键值对数据,再生成对应的一条指令进行保存,这个过程比较耗时,会对业务产生影响,所以Redis把重写的过程交给一个后台子进程来完成。这样子进程在重写过程里,主进程依然可以处理客户端请求。
为了避免子进程重写过程里,主进程数据发生变化,导致AOF文件和内存中数据不一致的问题,Redis在子进程重写过程里,主进程把数据变更追加到AOF重写缓冲区里,等到AOF文件重写完成之后,再把缓冲区里的数据追加到新的AOF文件里面。
优缺点,1.RDB每隔一定时间触发持久化,因此数据安全性较低,AOF可以做到实时持久化,数据安全性较高。
2.RDB文件默认采用压缩的方式持久化,AOF存储的是执行指令,所以RDB在数据恢复的时候性能比AOF好。
和MySQL的数据一致性
Redis用来实现应用和数据库之间的缓存层,减少数据库io,提升数据的io性能。当应用程序需要读取某个数据的时候,先去Redis里面加载,如果命中就直接返回,否则,查询数据库,查询到数据之后在把这个数据缓存到Redis里面。
当数据发生变化时,需要同时更新Redis和MySQL,由于更新是有先后顺序的,并且不像MySQL里多表事务操作满足acid特性,所以会出现数据一致性问题。
先更新数据库,再更新缓存,如果缓存更新失败,就会导致数据库和Redis数据不一致的问题。
先删除缓存,再更新数据库,理想情况下应用下次访问Redis的时候,发现Redis里的数据是空的,就从数据库加载保存到Redis里面,这样数据是一致的。但是由于删除Redis和更新数据库这2个操作不是原子的,这个过程有其他线程访问会导致数据不一致问题。
解决方案,采用最终一致性方案,
1.基于mq的可靠性消息通信来实现。失败的请求写入mq事务消息,异步重试,确保成功。
2.通过canal组件监控MySQL里binlog日志,把更新后的数据同步到Redis里面。
强一致性方案,可以对2个操作加锁,当MySQL和Redis的数据同步后释放锁,一旦其中任何一个组件更新失败,直接做回滚操作。但是这种设计性能不好。
内存淘汰算法
内存使用率到达内存上限的一种内存释放行为
random,随机删除某个key
ttl,删除最早过期的key
lru,删除最近最少使用key,常见内存淘汰算法,在Redis中维护一个大小为16的候选池,数据根据时间进行排序,每一次随机出5个key放入候选池,当候选池满了之后,访问时间间隔最大的key就会被淘汰。这样就可以把最少访问的key淘汰掉。
假如一个key的访问频率很低,但是最近一次偶尔被访问到,那么LRU认为是一个热点key,不会被淘汰。使用LFU算法解决,他增加了访问频率来统计数据热点情况。
lfu,删除最近不经常使用key,使用2个双向链表形成一个二维双向链表,一个用来保存访问的频率,一个用来保存访问频率相同的所有元素。当添加元素的时候,访问次数默认是1,找到相同访问频次的节点,然后添加到具有相同频率节点的链表的头部,当元素被访问的时候,就会增加对应key的访问频次,并且把当前访问节点移动到下一个频次节点。有可能出现某个数据前期访问次数很多,后续一直不用的情况,如果单纯按照频率淘汰key,那么这个key就很难被淘汰。所以在LFU通过使用频率和上次访问时间来标记数据的热度
minio
海量数据存储,人工智能,大数据分析而设计的对象存储系统。单个对象最大可达5TB,适合海量图片,视频,日志文件,备份数据等。采用golang语言实现,客户端使用Http与存储服务器通信。
安装部署简单,只需要执行几行命令完成部署,降低学习和维护成本
操作简单,自带UI管理界面,开箱即用。
性能优秀,每秒达到GB级别的读写速度
支持云原生容器部署。
提供多种语言的SDK支持
elasticsearch
基于全文搜索引擎库lucene基础上的开源搜索和分析引擎,具有分布式存储,检索速度快的特性,用来实现全文检索功能。
elastic stack 包括 elastic search 数据存储,logstash 数据采集 ,kibana 数据可视化,组合称为ELK,
elasticsearch 使用场景,网站搜索,日志聚焦,检索 涉及TB数据场景。
ES快的原因,1.ES是基于lucene开发的一个全文搜索引擎,一方面lucene擅长管理大量索引数据,另一方面对数据进行分词后再保存索引,提升了数据的检索效率
2.ES采用倒排索引,通过属性值来确定数据记录位置的索引,避免全表扫描。
3.分片机制存储数据
4.扩展性好,支持水平扩展的方式动态增加节点,从而提高性能。能够支持上白台服务器节点的扩展,支持TB级别的结构化和非结构化数据
5.提供数据汇总和索引生命周期管理,便于高效存储和检索数据。
缺点,1.不建议使用复杂的关联查询,影响性能
2.避免深度分页查询。ES分页通过from和size参数实现。查询的时候每个分片必须先构造一个长度为from+size的优先队列,然后回传给网关节点,网关节点再对这些优先队列排序,找到正确的size文档,在from足够大的情况下,容易造成oom网络传输性能低下问题。