NoSQL诞生的是为了解决现有关系型数据库所解决不了的问题。云计算时代对技术有了更高的要求,具体总结为4点,读写速度低延迟,可支持海量数据和流量,更简单的部署和管理分布式集群,减小越来越大的运营成本。而现有的主流的存储系统大部分还是采用了关系型数据库,其限制性很难满足以上需求。下面会从 NoSQL 的优势逐步聊到 redis 的一些重要概念,以及如何在分布式系统中应用。
关系型数据库的限制性
扩展困难:Join联合多表查询机制,使得数据库扩展艰难。
读写速度慢:当数据量很大时,由于关系型数据库的系统逻辑非常复杂,使得其很容易发生死锁等并发问题,导致读写速度下滑非常严重。
License成本高:企业级数据库的价格惊人,并且随着系统的规模而增加。
有限的支撑容量:现有关系型解决方案无法支撑Google这样海量的数据存储。
NoSQL数据库的特性
为了解决这些需求,很多新类型的数据被开发出来,它们在设计上非常关注对数据高并发地读写和对海量数据的存储,与关系型数据库相比,它们在架构和数据模型方面做了“减法”,而在扩展和并发等方面做了“加法”。 他们有一些共同的特性,而被统称为 NoSQL 数据库。
- 不再使用SQL语言,比如MongoDB、Cassandra就有自己的查询语言。
- 通常是开源项目。
- 为集群运行而生。
- 弱结构化,不会严格的限制数据结构类型。
现在主流的NoSQL数据库有BigTable、HBase、Cassandra、SimpleDB、CouchDB、MongoDB和Redis等。
NoSQL 数据库分类及适用场景
键值(Key-Value)数据库
键值数据库就像在传统语言中使用的哈希表,可以通过key来添加、查询或者删除数据,鉴于使用主键访问,所以会获得不错的性能及扩展性。
产品:Redis、Memcached、Riak、Amazon’s Dynamo
早期使用公司:GitHub(Riak)、BestBuy(Riak)、Twitter(Redis和Memcached)、StackOverFlow(Redis)、 Instagram(Redis)、Youtube(Memcached)、Wikipedia(Memcached)
键值数据库——适用场景
储存用户信息,比如会话、配置文件、参数、购物车等等。这些信息一般都和ID(键)挂钩,这种情景下键值数据库是个很好的选择。
键值数据库——不适用场景
取代通过键查询,而是通过值来查询。Key-Value数据库中根本没有通过值查询的途径。
需要储存数据之间的关系。在Key-Value数据库中不能通过两个或以上的键来关联数据。
事务的支持。在Key-Value数据库中故障产生时不可以进行回滚。
面向文档(Document-Oriented)数据库
面向文档数据库会将数据以文档的形式储存。每个文档都是自包含的数据单元,是一系列数据项的集合。每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串、数字和日期等;也可以是复杂的类型,如有序列表和关联对象。数据存储的最小单位是文档,同一个表中存储的文档属性可以是不同的,数据可以使用XML、JSON或者JSONB等多种形式存储。
产品:MongoDB、CouchDB、RavenDB
早期使用公司:SAP(MongoDB)、Codecademy(MongoDB)、Foursquare(MongoDB)、NBC News(RavenDB)
文档数据库——适用场景
日志。企业环境下,每个应用程序都有不同的日志信息。 Document-Oriented数据库并没有固定的模式,所以我们可以使用它储存不同的信息。
分析。鉴于它的弱模式结构,不改变模式下就可以储存不同的度量方法及添加新的度量。
文档数据库——不适用场景
在不同的文档上添加事务。Document-Oriented数据库并不支持文档间的事务,如果对这方面有需求则不应该选用这个解决方案。
列存储(Wide Column Store/Column-Family)数据库
列存储数据库将数据储存在列族(column family)中,一个列族存储经常被一起查询的相关数据。举个例子,如果我们有一个Person类,我们通常会一起查询他们的姓名和年龄而不是薪资。这种情况下,姓名和年龄就会被放入一个列族中,而薪资则在另一个列族中。
产品:Cassandra、HBase
早期使用公司:Ebay (Cassandra)、Instagram (Cassandra)、NASA (Cassandra)、Twitter (Cassandra and HBase)、Facebook (HBase)、Yahoo!(HBase)
列族数据库——适用场景
日志。因为我们可以将数据储存在不同的列中,每个应用程序可以将信息写入自己的列族中。
博客平台。我们储存每个信息到不同的列族中。举个例子,标签可以储存在一个,类别可以在一个,而文章则在另一个。
列族数据库——不适用场景
如果我们需要ACID事务。Cassandra就不支持事务。
原型设计。如果我们分析Cassandra的数据结构,我们就会发现结构是基于我们期望的数据查询方式而定。在模型设计之初,我们根本不可能去预测它的查询方式,而一旦查询方式改变,我们就必须重新设计列族。
图(Graph-Oriented)数据库
图数据库允许我们将数据以图的方式储存。实体会被作为顶点,而实体之间的关系则会被作为边。比如我们有三个实体,Steve Jobs、Apple和Next,则会有两个“Founded by”的边将Apple和Next连接到Steve Jobs。
产品:Neo4J、Infinite Graph、OrientDB
有谁在使用:Adobe (Neo4J)、Cisco (Neo4J)、T-Mobile (Neo4J)
图数据库——适用场景
在一些关系性强的数据中
推荐引擎。如果我们将数据以图的形式表现,那么将会非常有益于推荐的制定
图数据库——不适用场景
不适合的数据模型。图数据库的适用范围很小,因为很少有操作涉及到整个图。
言归正传——Redis特点
Redis是一个开源的使用C语言编写、开源、支持网络、可基于内存亦可持久化的日志型、高性能的Key-Value数据库,并提供多种语言的API。
Redis 与其他键值数据库相比,有如下3个特点
Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
Redis支持数据的备份,即master-slave模式的数据备份。
Redis优势
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 支持事务、单线程、原子性 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
redis相比memcached有哪些优势?
memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
redis的速度比memcached快很多
redis可以持久化其数据
Redis 数据类型
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String)、哈希(Hash)、 列表(list)、集合(sets)、有序集合(sorted sets/zset)等类型。
Redis 为什么要把所有数据放到内存中?
Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。
如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。
如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
Redis是单进程单线程的
redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销
虚拟内存的使用
当你的key很小而value很大时,使用VM的效果会比较好.因为这样节约的内存比较大.
当你的key不小时,可以考虑使用一些非常方法将很大的key变成很大的value,比如你可以考虑将key,value组合成一个新的value.
vm-max-threads这个参数,可以设置访问swap文件的线程数,设置最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的.
可能会造成比较长时间的延迟,但是对数据完整性有很好的保证.
自己测试的时候发现用虚拟内存性能也不错。如果数据量很大,可以考虑分布式或者其他数据库
Redis常见性能问题和解决方案:
Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
尽量避免在压力很大的主库上增加从库
主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3…