引言
伴随着数据信息化的发展,网站的访问量的提升,使用关系型数据库已经在性能上出现瓶颈,问题出现的源头一般是再磁盘的I/O上,因此随着互联网的发展,需要达到以下几个方面的需求:
1. 低延迟的读写速度:应用快速地反应能极大地提升用户的满意度 ;
2. 支撑海量的数据和流量:对于搜索这样大型应用而言,需要利用 PB级别的数据和能应对百万级的流量 ;
3. 大规模集群的管理:系统管理员希望分布式应用能更简单的部署和管理 ;
4. 庞大运营成本: IT经理们希望在硬件成本、软件成本和人力成本能够有大幅度地降低 ;
虽然关系型数据库已经在业界的数据存储方面占据不可动摇的地位,但是由于其天生的几个限制,使其很难满足上面这几个需求:
1. 扩展困难:由于存在类似 Join这样多表查询机制,使得数据库在扩展方面很艰难 ;
2. 读写慢:这种情况主要发生在数据量达到一定规模时由于关系型数据库的系统逻辑非常复杂,使得其非常容易发生死锁等的并发问题,所以导致其读写速度下滑非常严重 ;
3. 成本高:企业级数据库的 License价格很惊人,并且随着系统的规模,而不断上升 ;
4. 有限的支撑容量:现有关系型解决方案还无法支撑 Google这样海量的数据存储 ;
业界为了解决上面提到的几个需求,推出了多款新类型的数据库,并且由于它们在设计上和传统的 NoSQL数据库相比有很大的不同,所以被统称为 “NoSQL”系列数据库。总的来说,在设计上,它们非常关注对数据高并发地读写和对海量数据的存储等,与关系型数据库相比,它们在架构和数据模型方量面做了 “减法 ”,而在扩展和并发等方面做了 “加法 ”。现在主流的 NoSQL数据库有 BigTable、 HBase、 Cassandra、 SimpleDB、 CouchDB、 MongoDB和 Redis等。接下来,将关注 NoSQL数据库到底存在哪些优缺点。
Redis是什么?
Redis是一款内存高速缓存数据库。使用C语言编写,Redis是一个key-value存储系统(键值存储系统)。
Redis特点:
- 内存数据库,速度快,也支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
- 支持事务
Redis优势:
- 性能极高 – Redis能读的速度是110000次/s
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。(事务)
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
Redis与Memcache对比?
- Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等。
- Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
- 3、虚拟内存–Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘
- 过期策略–memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10
- 分布式–设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从
- 存储数据安全–memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化)
- 灾难恢复–memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复
- Redis支持数据的备份,即master-slave模式的数据备份。
Redis和Memcache的不同点
- 存储方式
memecache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小
redis有部份存在硬盘上,这样能保证数据的持久性,支持数据的持久化(笔者注:有RDB和AOF日志两种持久化方式。
- 数据支持类型
redis在数据支持上要比memecache多的多。
- 使用底层模型不同
新版本的redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
Redis支持数据类型
String(字符串)
String是简单的k-v键值对,需要注意的是一个键值对打存储512MB。
hash
hash是一个键值(key->value)对集合;是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
list
list列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
set
Set是string类型的无序集合。和列表一样,在执行插入和删除和判断是否存在某元素时,效率是很高的。集合最大的优势在于可以进行交集并集差集操作。Set可包含的最大元素数量是4294967295。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
zset
zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
Redis数据持久化
在redis中三个实现数据持久化有两种实现方式:
RDB:制定的时间间隔内对保存数据并快照,原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化(默认开启);
AOF:把命令追加到操作日志的尾部保存所有的历史操作,append only file原理是将Reids的操作日志以追加的方式写入文件。
二者区别
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程中是fork一个子进程,先将数据写入一个临时文件中,写入成功之过后,再替换之前的文件,用二进制压缩存储(dump.rbd文件)。
AOF持久化以日志形式记录服务器所处理的每一个写、删除操作,以文本形式保存(默认不开启)。
RDB和AOF触发机制
- RDB触发机制
- save触发方式:该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。
- bgsave触发方式:执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。
- 自动触发:自动触发是由我们的配置文件来完成的。在redis.conf配置文件中,里面有如下配置,我们可以去设置:
两种方式优缺点
1. RDB方式
•优点:
- RDB是一个单一的紧凑文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集.
- RDB是一个紧凑的单一文件,方便传送,适用于灾难恢复.
- RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能.
- 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些.
•缺点:
- Redis意外宕机,可能会丢失几分钟的数据(取决于配置的save时间点)。RDB方式需要保存珍整个数据集,是一个比较繁重的工作,通常需要设置5分钟或者更久做一次完整的保存。
- RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续更久。
2. AOF方式
•优点
- 使用AOF 会让Redis数据更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据。
- AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,也可使用redis-check-aof工具修复这些问题.
- Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
- AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析也很轻松。 导出AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis,就可以将数据集恢复到 FLUSHALL 执行之前的状态。
•缺点
- 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
- 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。在一般情况下,每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间。
Redis淘汰策略
- volatile-lru: 从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。
- volatile-ttl: 从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰volatile-random: 从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。
- allkeys-lru: 从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰。
- allkeys-random: 从数据集(server.db[i].dict)中任意选择数据淘汰。
- no-enviction: 禁止驱逐数据。