NoSQL-Redis

本文深入探讨了NoSQL数据库的CAP原理,介绍了Redis作为NoSQL数据库的特性,包括其单线程模型、数据结构(如String、Hash、List、Set、SortedSet)以及持久化机制。文章详细分析了Redis与memcached的对比,并展示了Redis在典型应用场景中的优势,如会话缓存、全页缓存、队列、排行榜以及计数器。此外,还讨论了Redis的主从复制、哨兵系统和集群方案,以及如何处理缓存雪崩、穿透和降级问题。最后,简要概述了SpringBoot中使用Spring Data Redis的编程实践。
摘要由CSDN通过智能技术生成

NoSQL

NoSQL即Not Only SQL不仅仅是SQL,泛指非关系型的数据库

NoSQL数据库可以分为4大类:键值key-value存储、列存储、文档数据库、图形数据库

CAP原理

CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。CAP原则是NOSQL数据库的基石。

分布式系统的CAP理论:理论首先把分布式系统中的三个特性进行了如下归纳:

  • 一致性C:在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
  • 可用性A:在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
  • 分区容忍性P:以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
  • 关系型数据库RDBMS:Oracle、MySQL就是CA
  • CP系统最典型的就是分布式数据库,如Redis、HBase等
  • AP高可用并允许分区,则需放弃一致性。例如抢购系统中,还有CouchDB之类的NoSQL数据库

BASE事务

分布式事务的特性BASE:基本可用BA、软状态S、最终一致性E

  • 基本可用Basically Available。NoSQL允许分布式系统中某些部分出现故障,那么系统的其余部分依然可用。它不会像ACID那样,在系统出现故障时,进行强制拒绝,允许继续部分访问。
  • 软状态Soft State。NoSQL在数据处理过程中,允许这个过程,存在数据状态暂时不一致的情况。但经过纠错处理,最终会一致的。
  • 最终一致性Eventually Consistent。NoSQL的软状态允许数据处理过程的暂时不一致,但是最终处理结果将是一致的,说明NoSQL对数据处理过程可以有短暂的时间间隔,也允许分更细的步骤一个一个地处理,最好数据达到一致即可。这在互联网上进行分布式应用具有其明显的优势。

Redis

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、高性能的Key-Value的NoSQL数据库。可以用作数据库、缓存、消息中间件等

Redis通常被称为数据结构服务器,因为值value可以是字符串String、哈希Map、列表list、集合set和有序集合sorted set等类型

  • 性能优秀,数据在内存中,读写速度非常快,支持并发 10W QPS
  • 单进程单线程,是线程安全的,采用 IO 多路复用机制
  • 丰富的数据类型,支持字符串strings、散列hashes、列表lists、集合sets、有序集合sorted sets等
  • 支持数据持久化。可以将内存中数据保存在磁盘中,重启时加载
  • 主从复制,哨兵,高可用
  • 可以用作分布式锁
  • 可以作为消息中间件使用,支持发布订阅

为什么使用Redis

1、解决应用服务器的cpu和内存压力

2、在项目中使用Redis,主要考虑两个角度:性能和并发。

3、在碰到需要执行耗时特别久,且结果不频繁变动的 SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。

4、在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。

5、排行榜及相关问题。排行榜按照得分进行排序。zadd命令可以直接实现这个功能,而zrevrange命令可以用来按照得分来获取前100名的用户,zrank可以用来获取用户排名,非常直接而且操作容易。

6、计数的问题,比如点赞和转发数,通过原子递增保持计数;getset用来重置计数器;过期属性用来确认一个关键字什么时候应该删除。

Redis优势
  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s
  • 丰富的数据类型 – Redis支持二进制的Strings, Lists, Hashes,Sets及Ordered Sets数据类型操作
  • 原子– Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来
  • 丰富的特性 – Redis还支持publish/subscribe,通知,key过期等等特性。
  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。
  • 支持数据持久化,支持AOF和RDB两种持久化方式。
Redis缺点
  • 数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
  • Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
  • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
  • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。
redis与memcache比较
  • Redis:多种结构 AE事件驱动 支持存儲 支持复制、单进程单线程[redis5+已经支持多线程]、Crash safe和Recovery slow,单机qps可以达到10W、适合小数据量高速读写访问。
  • Memcached:字符串 libEvent 不支持存儲 多线程、不能枚举全数据、性能仍有提升空间

1、存储方式上:Memcache 会把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。Redis 有部分数据存在硬盘上,这样能保证数据的持久性。

2、数据支持类型上:Memcache 对数据类型的支持简单,只支持简单的 key-value,,而 Redis 支持五种数据类型。

3、使用底层模型不同:它们之间底层实现方式以及与客户端之间通信的应用协议不一样。Redis 直接自己构建了 VM 机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

4、Value 的大小:Redis 可以达到 1GB,而 Memcache 只有 1MB

典型应用

1、会话缓存Session Cache。最常用的一种使用Redis的情景是会话缓存session cache。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化

2、全页缓存FPC。除基本的会话token之外,Redis还提供很简便的FPC平台

3、队列。Reids在内存存储提供list和set操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作

4、排行榜/计数器。Redis在内存中对数字进行递增或递减的操作实现的非常好。集合Set和有序集合Sorted Set也使得在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”

5、发布/订阅。可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统。

Redis6多线程

主线程还是单线程的,只是IO线程采用多线程方式。

Redis 6.0默认并没有开启多线程,可以在conf文件进行配置

  • io-threads-do-reads yes
  • io-threads 线程数

官方建议:4 核的机器建议设置为2或3个线程,8核的建议设置为6个线程,线程数一定要小于机器核数,尽量不超过8个。

开启多线程后,是否会存在线程并发安全问题?

不会,Redis的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程顺序执行。

AE事件模型

redis采用网络IO多路复用技术来保证在多连接的时候, 系统的高吞吐量。多路指的是多个Socket连接,复用指的是复用一个线程。多路复用主要有三种技术:Select,Poll,Epoll。

Redis使用了一个称为A simple event-driven programming library的自制异步事件库,简称AE。Redis默认采用epoll。主要提供了对两种类型的事件驱动:1、IO事件(文件事件),包括有IO的读事件和写事件。2、定时器事件,包括有一次性定时器和循环定时器。

Redis为什么这么快

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1);

2、数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的;

3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗

4、使用多路 I/O 复用模型,非阻塞 IO;

5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM机制 ,因为一般的系统调用系统函数的话会浪费一定的时间去移动和请求;

Redis是单线程的,如何提高多核CPU的利用率

可以在同一个服务器部署多个Redis的实例,并把他们当作不同的服务器来使用,在某些时候,无论如何一个服务器是不够的, 所以,如果想使用多个CPU可以考虑一下分片shard。

redis应用体系结构

Sentinel/san’te’nao/是面向分布式服务架构的轻量级流量控制产品,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性

  • 单机版Redis Server,无Sentinel。会有单点故障的问题无法解决,如果没有配置Redis数据持久化的话,Redis内部已经存储的数据也会丢失

  • 主从同步Redis Server,单实例Sentinel

    即在两台服务器上分别各启动一个Redis Server进程,一般情况下由master提供服务,slave只负责同步和备份。与此同时在额外启动一个Sentinel进程,监控两个Redis Server实例的可用性,以便在master宕机时及时把slave提升到master的角色继续提供服务,这样就实现了Redis Server的高可用。这基于一个高可用服务设计的依据,即单点故障本身就是个小概率事件,而多个单点同时故障(即master和slave同时挂掉),可以认为是基本不可能发生的事件

  • 主从同步Redis Server,三实例Sentinel

    把Redis Sentinel进程也额外启动一份,三个Sentinel进程同时为客户端提供服务发现的功能,引入了服务器3上搭建起一个Redis Sentinel进程,现在由三个Sentinel进程来管理两个Redis Server实例。对于客户端来说,它可以连接任何一个Redis Sentinel服务来获取当前Redis Server实例的基本信息。通常情况下会在Client端配置多个Redis Sentinel的链接地址,Client一旦发现某个地址连接不上,会去试图连接其他的Sentinel实例

  • Redis集群的数据分片redis-cluster

    利用【集群+槽位】的方式完成,Redis集群没有使用一致性哈希,而是另外一种不同的分片形式,每个键概念上是被称为哈希槽hash slot。Redis集群有16384个哈希槽,使用键的CRC16编码对16384取模来计算一个指定键所属的哈希槽。 每个Redis集群中的节点都承担一个哈希槽的子集

  • Redis集群的主从模型Redis Cluster master-slave model

    为了当部分节点失效时或者无法与大多数节点通信时仍能保持可用,Redis集群采用每个节点拥有1(主服务自身)到N个副本(N-1个附加的从服务器)的主从模型。假设集群拥有A,B,C三个节点,如果节点B失效集群将不能继续服务,因为不再有办法来服务在5501-11000范围内的哈希槽。 但是,如果当创建集群后为每个主服务器添加一个从服务器,这样最终的集群就由主服务器A,B,C和从服务器A1,B1,C1组成,如果B节点失效系统仍能继续服务。B1节点复制B节点,于是集群会选举B1节点作为新的主服务器,并继续正确的运转。

redis.windows.conf

  • daemonize no默认情况下redis不是作为守护进程运行的,如果想让它在后台运行,就把它改成yes。当redis作为守护进程运行的时候,它会写一个pid到/var/run/redis.pid文件里面
  • port 6379监听端口号,默认为6379,如果设为0,redis将不在socket上监听任何客户端连接。
  • tcp-backlog 511设置TCP监听的最大容纳数量。在高并发的环境下,需要把这个值调高以避免客户端连接缓慢的问题。Linux内核会把这个值缩小成/proc/sys/net/core/somaxconn对应的值,所以要修改这两个值才能达到你的预期。
  • bind 192.168.1.100 10.0.0.1默认情况下,redis在server上所有有效的网络接口上监听客户端连接。如果只想让它在一个网络接口上监听,那就绑定一个IP或者多个IP。多个IP用空格隔开
  • timeout 0指定在一个client空闲多少秒之后关闭连接(0就是不管它)
  • loglevel notice定义日志级别。可以是:debug适用于开发或测试阶段、verbose类似debug信息但是内容更少些、notice适用于生产环境、warning仅仅一些重要的消息被记录

基本操作中的问题

问题1:假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?

使用keys指令可以扫出指定模式的key列表。

对方接着追问:如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题?

这个时候要回答redis关键的一个特性:r

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值