NoSQL 数据库 Redis

NoSQL 和 Redis 特性

NoSQL 数据库基础

数据库主要分为两大类:关系型数据库与 NoSQL 数据库

关系型数据库,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库 中的数据。主流的 MySQL、Oracle、MS SQL Server 和 DB2 都属于这类传统数据库

NoSQL 数据库,全称为 Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适 用的时候可以考虑使用更加合适的数据存储。NoSQL 是对不同于传统的关系型数据库的数据库管理系统的统称

NoSQL 的 RDBMS 比较

关系型数据库管理系统(RDBMS)和NoSQL数据库各有优缺点,适用于不同的应用场景。以下是它们 在几个关键方面的对比

数据模型

RDBMS

  • 使用表格来表示数据,具有严格的模式(schema)

  • 表与表之间通过外键建立关系

  • 适合结构化数据,适用于事务处理和关系密集型的应用

NoSQL

  • 使用多种数据模型,包括文档、键值对、列存储和图

  • 没有固定的模式,数据模型更加灵活

  • 适合半结构化和非结构化数据,适用于数据结构频繁变化的应用

查询语言

RDBMS

  • 使用结构化查询语言(SQL)进行数据查询和管理

  • SQL标准化程度高,易于学习和使用,拥有丰富的查询功能

NoSQL

  • 不使用标准的SQL,各种NoSQL数据库有自己的查询语言或API

  • 查询功能因数据库类型不同而异,灵活性高但学习曲线较陡

可扩展性

RDBMS

  • 通常是垂直扩展(通过增加单个服务器的资源来提升性能)

  • 水平扩展(通过增加更多的服务器来提升性能)比较困难

NoSQL

  • 设计为水平扩展,可以通过增加更多的服务器来处理更多的数据和请求

  • 非常适合大规模分布式系统

一致性和事务

RDBMS

  • 遵循ACID(原子性、一致性、隔离性、持久性)原则,确保数据的一致性和可靠性

  • 适合需要强一致性和复杂事务的应用

NoSQL

  • 更强调CAP定理(一致性、可用性、分区容忍性)中的可用性和分区容忍性

  • 通常支持最终一致性,但也有一些NoSQL数据库(如MongoDB)提供事务支持

性能

RDBMS

  • 在处理复杂查询和事务时性能较好

  • 适合读写操作较少但查询复杂度高的应用

NoSQL

  • 在读写操作频繁、需要高吞吐量和低延迟的场景中表现优越

  • 适合需要快速读写、海量数据处理的应用

数据完整性

RDBMS

  • 通过外键、唯一性约束等机制确保数据完整性

  • 更适合需要严格数据完整性和约束的应用

NoSQL

  • 数据完整性主要由应用程序层来管理

  • 更灵活,但数据一致性和完整性需要更小心地处理

典型应用场景

RDBMS

  • 金融系统、电子商务系统、企业资源计划(ERP)系统、人力资源管理(HRM)系统等需要强一致 性和复杂事务的应用

NoSQL

  • 社交网络、内容管理系统(CMS)、物联网(IoT)、实时数据处理、大数据分析等需要高扩展性 和灵活数据模型的应用

总结

RDBMS

  • 优点:数据一致性强、事务支持、标准化查询语言、数据完整性好

  • 缺点:扩展性有限、灵活性较差、在大规模数据处理中的性能瓶颈

NoSQL

  • 优点:高扩展性、灵活的数据模型、高性能读写、适应大规模数据处理。

  • 缺点:一致性和事务支持相对较弱、查询语言不统一、数据完整性依赖应用程序

NoSQL数据库的发展是对现代应用需求的回应,它们在大数据、实时应用和分布式系统中的表现,使其 成为传统关系型数据库的重要补充和替代方案

选择RDBMS还是NoSQL取决于具体的应用需求和场景。对于需要严格事务和数据一致性的应用, RDBMS可能更适合;而对于需要处理海量数据和高并发访问的应用,NoSQL则可能是更好的选择

CAP 定理和Base理论

CAP 定理

C:Consistency

即一致性, 所有节点在同一时间具有相同的数据视图

换句话说,如果一个节点在写入操作完成后,所有其他节点都能立即读取到最新的数据

注意,这里的一致性指的是强一致性,也就是数据更新完,访问任何节点看到的数据完全一致,要和弱 一致性,最终一致性区分开来

每次读取的数据都应该是最近写入的数据或者返回一个错误, 而不是过期数据,也就是说,所有节点的数 据是一致的

A:Availability

即可用性,所有的节点都保持高可用性

每个非故障节点都能够在有限的时间内返回有效的响应,即系统一直可用。可用性强调系统对用户请求 的及时响应

注意,这里的高可用还包括不能出现延迟,比如如果某个节点由于等待数据同步而阻塞请求,那么该节 点就不满足高可用性

也就是说,任何没有发生故障的服务必须在有限的时间内返回合理的结果集

每次请求都应该得到一个有效的响应,而不是返回一个错误或者失去响应,不过这个响应不需要保证数 据是最近写入的,也就是说系统需要一直都是可用正常使用的,不会引起调用者的异常,但是并不保证 响应的数据是最新的

P:Partiton tolerance

即分区容忍性,系统能够在网络分区的情况下继续运行。分区是指系统中的节点由于网络故障无法相互 通信,导致系统被分成多个孤立的子系统

由于网络是不可靠的,所有节点之间很可能出现无法通讯的情况,在节点不能通信时,要保证系统可以继续正常服务

在分布式系统中,机器分布在各个不同的地方,由网络进行连接。由于各地的网络情况不同,网络的延 迟甚至是中断是不可避免的。分区容错性指的就是服务器之间通信异常的情况

遵循CAP原理,一个数据分布式系统不可能同时满足C和A和P这3个条件。所以系统架构师在设计系统 时,不要将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍。由于网络的不可靠 的性质,大多数开源的分布式系统都会实现P,也就是分区容忍性,之后在C和A中做抉择

因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三大类

CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大

CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。 放弃可用性,追求强一致性和分区容错性

AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些

通常实现AP都会保证最终一致性,而BASE理论就是根据AP来扩展的,一些业务场景 比如:订单退款, 今日退款成功,明日账户到账,只要用户可以接受在一定时间内到账即可

Base理论

Base理论是三要素的缩写:基本可用(Basically Available)、软状态(Soft-state)、最终一致性 (Eventually Consistency)

基本可用 (Basically Available)

相对于CAP理论中可用性的要求:【任何时候,读写都是成功的】,“基本可用”要求系统能够基本运行, 一直提供服务,强调的是分布式系统在出现不可预知故障的时候,允许损失部分可用性。比如系统通过 断路保护而引发快速失败,在快速失败模式下,支持加载默认显示的内容(静态化的或者被缓存的数 据),从而保证服务依然可用

软状态 (Soft state)

相对于ACID事务中原子性要求的要么全做,要么全不做,强调的是强制一致性,要求多个节点的数据副 本是一致的,强调数据的一致性。这种原子性可以理解为 “硬状态“,而软状态则允许系统中的数据存在 中间状态,并认为该状态不影响系统的整体可用性,即允许系统在不同节点的数据副本上存在数据延时

最终一致性(Eventuallyconsistent)

数据不可能一直处于软状态,必须在一个时间期限后达到各个节点的一致性。在期限过后,应当保证所 有副本中的数据保持一致性,也就是达到了数据的最终一致性,在系统设计中,最终一致性实现的时间 取决于网络延时、系统负载、不同的存储选型,不同数据复制方案设计等因素。也就是说,不保证用户 什么时候能看到更新完成后的数据,但是终究会看到的

NoSQL 数据库分类

类型 部分代表 特点
列存储 Hbase 顾名思义,是按列存储数据的。最大的特点是方便存 储结构化和半结构化数据,方便做数据压缩,对针对 某一列或者某几列的查询有非常大的IO优势
文档存储 MongoDB, CouchDB 文档存储一般用类似json的格式存储,存储的内容是 文档型的。这样也就有机会对某些字段建立索引,实 现关系数据库的某些功能
Key-Value 存储 Memcached, Redis 可以通过key快速查询到其value。一般来说,存储不 管value的格式,照单全收。(Redis包含了其他功能)
图存储 Neo4JFlockDB 图形关系的最佳存储。使用传统关系数据库来解决的 话性能低下,而且设计使用不方便
对象存储 db4oVersant 通过类似面向对象语言的语法操作数据库,通过对象 的方式存取数据
XML 数据 库 Berkeley DB XMLBaseX 高效的存储XML数据,并支持XML的内部查询语法,比如 XQuery,Xpath

Redis 基础

Redis(Remote Dictionary Server远程字典服务)是一个遵循 BSD MIT 开源协议的高性能的 NoSQL

Redis 基于ANSI C 语言语言编写的 key-value 数据库,是意大利的 Salvatore Sanfilippo 在 2009 年发 布从 2010年3月15日起,Redis 的开发工作由VMware主持,从2013年5月开始,Redis 的开发由 Pivotal 公司赞助。目前国内外使用的公司众多,比如:阿里,腾讯,百度,京东,新浪微博,GitHub, Twitter 等

Redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库 起到很好的补充作用。它提供了Java,C/C++,Go, C#,PHP,JavaScript,Perl,Object-C,Python, Ruby,Erlang 等客户端

Redis 特性

  • 高性能:基于内存,读写操作快速,适用于高性能需求的场景

  • 丰富的数据结构:支持字符串,哈希,列表,集合等多种数据结构

  • 持久化:支持 RDB 和 AOF 两种方式对内存中的数据进行持久化操作

  • 发布/订阅:支持实时消息发布和通知

  • 多种语言客户端:支持 java,python,C/C++,PHP 等主流编程语言

  • Lua脚本:服务器端运行Lua脚本,提供原子性操作

  • 主从复制:数据从主节点复制到从节点,实现数据冗余和负载均衡

  • 高可用和分布式:支持哨兵和集群两种方式实现高可用和分布式

  • 生周周期:支持数据自动过期,支持数据自动淘汰

Redis 中的单线程

Redis单线程设计在高性能、高并发场景中表现优越,同时有多种优化手段应对性能瓶颈

Redis中的单线程指的是Redis使用单线程处理所有客户端请求,即所有命令按顺序执行,不并行处理 而不是说 Redis 服务中只有一个线程

单线程的优点:

  • 简单:无需处理多线程同步和锁问题

  • 高效:避免上下文切换和锁争用

  • 低延迟:请求处理时间短,保持低延迟

单线程的缺点:

  • CPU 瓶颈:单线程在CPU密集型任务下可能成为瓶颈,无法发挥服务器多核心的作用

  • 慢查询:长时间查询会阻塞请求

Redis 和 Memcached 比较

Redis和Memcached都是流行的内存缓存系统,但在特性和应用场景上有显著差异

特性 Redis Memcached
数据结构 支持多种数据结构(字符串、哈希、列 表、集合等) 仅支持简单的键值对
持久化 支持(RDB和AOF) 不支持
主从复制和高可用 支持主从复制、哨兵和集群模式 不支持原生复制和故障转移,依赖客户端实现
内存管理 灵活,支持多种淘汰策略(如LRU、 LFU) 简单,基于LRU策略
性能 高性能,适合复杂操作和实时处理,单线 程设计 极高性能,适合简单键值对操作, 多线程设计
应用场景 缓存、会话存储、实时数据处理、消息队 列等复杂场景 简单、高性能的键值对缓存

Redis 应用场景

缓存

  • 应用程序缓存:提高数据访问速度,减少数据库负载

  • 网页缓存:缓存动态网页生成的内容,加快响应时间

会话存储

  • 用户会话管理:存储用户登录状态和会话数据,支持快速访问和过期管理

消息队列

  • 发布/订阅系统:实现实时消息分发和事件通知

  • 任务队列:使用列表(List)实现任务队列,支持任务的推送和弹出

实时数据分析

  • 计数器和排行榜:使用有序集合(Sorted Set)实现实时统计和排名

  • 实时监控和报警:存储和分析实时数据流,支持快速报警

数据存储

  • 配置管理:存储和快速访问应用配置数据

  • 地理位置数据:使用GEO命令存储和查询地理位置数据

分布式锁

  • 分布式锁:使用SETNX命令实现分布式锁,确保多实例环境中的操作一致性

数据过期和淘汰

  • 键过期:设置键的过期时间,实现自动删除过期数据

  • 数据淘汰:使用不同的淘汰策略管理内存使用,确保数据新鲜度

秒杀系统

  • 高并发处理:缓存热点数据和库存信息,快速响应高并发请求

  • 限流:使用令牌桶算法或计数器实现限流,防止系统过载

社交网络

  • 好友列表和关注关系:使用集合(Set)和有序集合(Sorted Set)存储和管理用户关系

  • 时间线和动态:使用列表(List)存储用户发布的动态信息,支持快速查询和更新

分布式集群管理

  • Redis哨兵(Sentinel):实现高可用性和自动故障转移

  • Redis集群(Cluster):实现数据分片和分布式存储,支持大规模数据存储和高并发访问

缓存穿透,缓存击穿和缓存雪崩

缓存穿透 Cache Penetration

缓存穿透是指查询一个根本不存在的数据。由于缓存中没有这个数据的缓存,自然也就不会缓存这个数 据的请求,导致每次请求都会直接穿透缓存,查询数据库

解决方法:

  • 布隆过滤器(Bloom Filter):在缓存前增加一个布隆过滤器,用于判断请求的数据是否存在,如果不存在则直接返回,避免查询数据库

  • 缓存空值:对于不存在的数据,将空结果缓存起来,设置一个较短的过期时间,防止频繁查询数据库

缓存击穿 Cache break down

缓存击穿是指某个热点数据的缓存失效后,有大量请求同时到达缓存但缓存中没有该数据,从而导致请求直接打到数据库上,可能会造成数据库压力过大

解决方法:

  • 互斥锁(Mutex):在缓存失效时,通过加锁的方式,只有一个线程能去加载数据,其他线程等待,防止同时对数据库造成压力

  • 提前更新(Pre-warm):在缓存即将失效时,提前异步更新缓存,避免缓存失效后大量请求直接打到数据库

  • 设置热点数据永远不过期

缓存雪崩 Thunder Hurd Problem

缓存雪崩是指缓存服务器大量缓存数据在同一时间失效或者缓存服务器宕机,导致大量请求直接打到数据库上,造成数据库过载

解决方法:

  • 缓存失效时间设置随机化:为不同的缓存设置不同的失效时间,避免大量缓存同时失效

  • 多级缓存(Multi-level Cache):通过使用本地缓存和远程缓存的多级缓存策略,降低缓存失效对 数据库的影响

  • 限流和降级:当发现数据库负载过高时,通过限流和服务降级措施,保护数据库不被过载

你可能感兴趣的:(数据库,nosql,redis)