> 文章列表 > MongoDBRedis基础知识

MongoDBRedis基础知识

MongoDBRedis基础知识

MongoDB&Redis基础知识

  • 1. MongoDB简介
  • 2. Redis

关系型数据库遵循ACID原则:

  • 原子性
  • 一致性
  • 独立性
  • 持久性

分布式系统:由多台计算机和通信的软件组件通过计算机网络连接组成,分布式系统是建立在网络之上的软件系统,因为软件的特性,所以分布式系统具有高度的内聚性和透明性。

网络和分布式系统之间的区别更多的在于高层软件而不是硬件

分布式计算的有点:

  • 可靠性
  • 可扩展性
  • 资源共享
  • 灵活性
  • 高速
  • 开放
  • 高性能

1. MongoDB简介

由C++语言编写的,基于分布式文件存储的开源数据库系统。

在高负载时,添加更多节点,可以保证服务器的性能。

MongoDB旨在为WEB应用提供可扩展的高性能数据存储解决方案

MongoDB将数据存储为一个文档,数据结构由键值对构成,类似json对象,字段值可以包含其他文档、数组以及文档数组

特点:

  • 面向文档存储的数据库
  • 在MongoDB记录中设置任何属性的索引来实现更快的排序和查找
  • 支持丰富的查询表达式
  • map/reduce进行数据的批量处理和聚合操作
  • 允许服务执行脚本(JavaScript)
  • 支持各种编程语言

基础
MongoDBRedis基础知识

2. Redis

全名remote dictionary server,是一个开源的使用ANSI C语言编写的,支持网络,可基于内存,可持久化的日志型,键值对数据库。

与MYSQL数据库不同的是,redis的数据存于内存中,读写速度非常快,每秒可以处理超过10万次读写操作。因此redis被广泛应用于缓存

此外redis也经常用于做分布式锁,并支持事务、持久化、LUA脚本、LRU驱动事件、多种集群方案

五种基本数据类型:

  • 字符串:使用SDS封装

使用simple dynamic string的原因:一些基础操作更加高效:获取字符串长度O(1)时间复杂度

空间预分配

惰性空间释放

二进制安全

  • 哈希:哈希类型指v值本身又是一个键值对
  • 列表:存储多个有序字符串

应用场景:栈、队列、有限集合、消息队列

  • 集合:保存多个字符串元素,不允许重复元素
  • 有序集合:已排序的字符串集合,元素不能重复

三种特殊结构:

  • geospatial:地理位置定位,存储地理位置信息
  • hpyerloglog:用于做基数统计算法的数据机构,如统计网站的UV
  • bitmap:位图,用比特位映射元素状态

MongoDBRedis基础知识

MYSQL索引为了提高效率,选择了B+树的数据结构

跳跃表是redis特有的数据结构,在链表的基础上,增加多级索引提升查找效率

合理的线程模型:

I/O多路复用:让单个线程高效的处理多个连接请求,使用epoll作为技术上的实现,redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多时间

  • I/O :网络 I/O
  • 多路 :多个网络连接
  • 复用:复用同一个线程。
  • IO多路复用其实就是一种同步IO模型,它实现了一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;而没有文件句柄就绪时,就会阻塞应用程序,交出cpu。

单线程模型

Redis是单线程模型的,而单线程避免了CPU不必要的上下文切换和竞争锁的消耗。也正因为是单线程,如果某个命令执行过长(如hgetall命令),会造成阻塞。Redis是面向快速执行场景的数据库。,所以要慎用如smembers和lrange、hgetall等命令。
Redis 6.0 引入了多线程提速,它的执行命令操作内存的仍然是个单线程。

redis自己构建了VM机制:

虚拟内存机制就是暂时把不经常访问的数据(冷数据)从内存交换到磁盘中,从而腾出宝贵的内存空间用于其它需要访问的数据(热数据)。通过VM功能可以实现冷热数据分离,使热数据仍在内存中、冷数据保存到磁盘。这样就可以避免因为内存不足而造成访问速度下降的问题。

缓存穿透: 读请求访问时,缓存和数据库都没有某个值,这样就会导致每次对这个值的查询请求都会穿透到数据库,这就是缓存穿透。

产生原因:

  • 业务不合理的设计,比如大多数用户都没开守护,但是你的每个请求都去缓存,查询某个userid查询有没有守护。
  • 业务/运维/开发失误的操作,比如缓存和数据库的数据都被误删除了。
  • 黑客非法请求攻击,比如黑客故意捏造大量非法请求,以读取不存在的业务数据。

如何避免缓存穿透?

1.如果是非法请求,我们在API入口,对参数进行校验,过滤非法值。
2.如果查询数据库为空,我们可以给缓存设置个空值,或者默认值。但是如有有写请求进来的话,需要更新缓存哈,以保证缓存一致性,同时,最后给缓存设置适当的过期时间。(业务上比较常用,简单有效)
3.使用布隆过滤器快速判断数据是否存在。即一个查询请求过来时,先通过布隆过滤器判断值是否存在,存在才继续往下查。

缓存雪奔: 指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,引起数据库压力过大甚至down机。

Redis 故障宕机也可能引起缓存雪奔。这就需要构造Redis高可用集群

缓存击穿: 指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db

解决方案:

使用互斥锁方案。缓存失效时,不是立即去加载db数据,而是先使用某些带成功返回的原子操作命令,如(Redis的setnx)去操作,成功的时候,再去加载db数据库数据和设置缓存。否则就去重试获取缓存。

“永不过期”,是指没有设置过期时间,但是热点数据快要过期时,异步线程去更新和设置过期时间。