知足常乐|学习Redis从这里开始( 二 )


表1-1展示了一部分在功能上与Redis有重叠的数据库服务器和缓存服务器 , 从这个表可以看出Redis与这些数据库及软件之间的区别 。
知足常乐|学习Redis从这里开始
文章图片
表1-1一些数据库和缓存服务器的特性与功能
在使用类似Redis这样的内存数据库时 , 一个首先要考虑的问题就是“当服务器被关闭时 , 服务器存储的数据将何去何从呢?”Redis拥有两种不同形式的持久化方法 , 它们都可以用小而紧凑的格式将存储在内存中的数据写入硬盘:第一种持久化方法为时间点转储(point-in-timedump) , 转储操作既可以在“指定时间段内有指定数量的写操作执行”这一条件被满足时执行 , 又可以通过调用两条转储到硬盘(dump-to-disk)命令中的任何一条来执行;第二种持久化方法将所有修改了数据库的命令都写入一个只追加(append-only)文件里面 , 用户可以根据数据的重要程度 , 将只追加写入设置为从不同步(sync)、每秒同步一次或者每写入一个命令就同步一次 。 我们将在第4章中更加深入地讨论这些持久化选项 。
另外 , 尽管Redis的性能很好 , 但受限于Redis的内存存储设计 , 有时候只使用一台Redis服务器可能没有办法处理所有请求 。 因此 , 为了扩展Redis的读性能 , 并为Redis提供故障转移(failover)支持 , Redis实现了主从复制特性:执行复制的从服务器会连接上主服务器 , 接收主服务器发送的整个数据库的初始副本(copy);之后主服务器执行的写命令 , 都会被发送给所有连接着的从服务器去执行 , 从而实时地更新从服务器的数据集 。 因为从服务器包含的数据会不断地进行更新 , 所以客户端可以向任意一个从服务器发送读请求 , 以此来避免对主服务器进行集中式的访问 。 我们将在第4章中更加深入地讨论Redis从服务器 。
有memcached使用经验的读者可能知道 , 用户只能用APPEND命令将数据添加到已有字符串的末尾 。 memcached的文档中声明 , 可以用APPEND命令来管理元素列表 。 这很好!用户可以将元素追加到一个字符串的末尾 , 并将那个字符串当作列表来使用 。 但随后如何删除这些元素呢?memcached采用的办法是通过黑名单(blacklist)来隐藏列表里面的元素 , 从而避免对元素执行读取、更新、写入(包括在一次数据库查询之后执行的memcached写入)等操作 。 相反地 , Redis的LIST和SET允许用户直接添加或者删除元素 。
使用Redis而不是memcached来解决问题 , 不仅可以让代码变得更简短、更易懂、更易维护 , 而且还可以使代码的运行速度更快(因为用户不需要通过读取数据库来更新数据) 。 除此之外 , 在其他许多情况下 , Redis的效率和易用性也比关系数据库要好得多 。
【知足常乐|学习Redis从这里开始】数据库的一个常见用法是存储长期的报告数据 , 并将这些报告数据用作固定时间范围内的聚合数据(aggregates) 。 收集聚合数据的常见做法是:先将各个行插入一个报告表里面 , 之后再通过扫描这些行来收集聚合数据 , 并根据收集到的聚合数据来更新聚合表中已有的那些行 。 之所以使用插入行的方式来存储 , 是因为对于大部分数据库来说 , 插入行操作的执行速度非常快(插入行只会在硬盘文件末尾进行写入) 。 不过 , 对表里面的行进行更新却是一个速度相当慢的操作 , 因为这种更新除了会引起一次随机读(randomread)之外 , 还可能会引起一次随机写(randomwrite) 。 而在Redis里面 , 用户可以直接使用原子的(atomic)INCR命令及其变种来计算聚合数据 , 并且因为Redis将数据存储在内存里面2 , 而且发送给Redis的命令请求并不需要经过典型的查询分析器(parser)或者查询优化器(optimizer)进行处理 , 所以对Redis存储的数据执行随机写的速度总是非常迅速的 。