Redis是一个远程内存数据库,它不仅性能强劲,而且还具有复制特性以及为解决问题而生的独一无二的数据模型。Redis提供了5种不同类型的数据结构,各式各样的问题都可以很自然地映射到这些数据结构上:Redis的数据结构致力于帮助用户解决问题,而不会像其他数据库那样,要求用户扭曲问题来适应数据库。除此之外,通过复制、持久化(persistence)和客户端分片(client-side sharding)等特性,用户可以很方便地将Redis扩展成一个能够包含数百GB数据、每秒处理上百万次请求的系统。

  笔者第一次使用Redis是在一家公司里面,这家公司需要对一个保存了6万个客户联系方式的关系数据库进行搜索,搜索可以根据名字、邮件地址、所在地和电话号码来进行,每次搜索需要花费10~15秒的时间。在花了一周时间学习Redis的基础知识之后,我使用Redis重写了一个新的搜索引擎,然后又花费了数周时间来仔细测试这个新系统,使它达到生产级别,最终这个新的搜索系统不仅可以根据名字、邮件地址、所在地和电话号码等信息来过滤和排序客户联系方式,并且每次操作都可以在50毫秒之内完成,这比原来的搜索系统足足快了 200 倍。

1、Redis简介

  前面对于Redis数据库的描述只说出了一部分真相。Redis是一个速度非常快的非关系数据库(non-relational database),它可以存储键(key)与5种不同类型的值(value)之间的映射(mapping),可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用客户端分片1来扩展写性能。

2、使用Redis的理由

  有memcached使用经验的读者可能知道,用户只能用APPEND命令将数据添加到已有字符串的末尾。memcached的文档中声明,可以用APPEND命令来管理元素列表。这很好!用户可以将元素追加到一个字符串的末尾,并将那个字符串当作列表来使用。但随后如何删除这些元素呢?memcached采用的办法是通过黑名单(blacklist)来隐藏列表里面的元素,从而避免对元素执行读取、更新、写入(包括在一次数据库查询之后执行的memcached写入)等操作。相反地,Redis的LIST和SET允许用户直接添加或者删除元素。

  使用Redis而不是memcached来解决问题,不仅可以让代码变得更简短、更易懂、更易维护,而且还可以使代码的运行速度更快(因为用户不需要通过读取数据库来更新数据)。除此之外,在其他许多情况下,Redis的效率和易用性也比关系数据库要好得多。

  数据库的一个常见用法是存储长期的报告数据,并将这些报告数据用作固定时间范围内的聚合数据(aggregates)。收集聚合数据的常见做法是:先将各个行插入一个报告表里面,之后再通过扫描这些行来收集聚合数据,并根据收集到的聚合数据来更新聚合表中已有的那些行。之所以使用插入行的方式来存储,是因为对于大部分数据库来说,插入行操作的执行速度非常快(插入行只会在硬盘文件末尾进行写入)。不过,对表里面的行进行更新却是一个速度相当慢的操作,因为这种更新除了会引起一次随机读(random read)之外,还可能会引起一次随机写(random write)。而在Redis里面,用户可以直接使用原子的(atomic)INCR命令及其变种来计算聚合数据,并且因为Redis将数据存储在内存里面2,而且发送给Redis的命令请求并不需要经过典型的查询分析器(parser)或者查询优化器(optimizer)进行处理,所以对Redis存储的数据执行随机写的速度总是非常迅速的。

  使用 Redis 而不是关系数据库或者其他硬盘存储数据库,可以避免写入不必要的临时数据,也免去了对临时数据进行扫描或者删除的麻烦,并最终改善程序的性能。虽然上面列举的都是一些简单的例子,但它们很好地证明了“工具会极大地改变人们解决问题的方式”这一点。

3、Redis与其他数据库和软件的对比

  如果你熟悉关系数据库,那么你肯定写过用来关联两个表的数据的SQL查询。而Redis则属于人们常说的NoSQL数据库或者非关系数据库:Redis不使用表,它的数据库也不会预定义或者强制去要求用户对Redis存储的不同数据进行关联。

  高性能键值缓存服务器memcached也经常被拿来与Redis进行比较:这两者都可用于存储键值映射,彼此的性能也相差无几,但是Redis能够自动以两种不同的方式将数据写入硬盘,并且Redis除了能存储普通的字符串键之外,还可以存储其他4种数据结构,而memcached只能存储普通的字符串键。这些不同之处使得Redis可以用于解决更为广泛的问题,并且既可以用作主数据库(primary database)使用,又可以作为其他存储系统的辅助数据库(auxiliary database)使用。

  本书的后续章节会分别介绍将Redis用作主存储(primary storage)和二级存储(secondary storage)时的用法和查询模式。一般来说,许多用户只会在Redis的性能或者功能是必要的情况下,才会将数据存储到Redis里面:如果程序对性能的要求不高,又或者因为费用原因而没办法将大量数据存储到内存里面,那么用户可能会选择使用关系数据库,或者其他非关系数据库。在实际中,读者应该根据自己的需求来决定是否使用Redis,并考虑是将Redis用作主存储还是辅助存储,以及如何通过复制、持久化和事务等手段保证数据的完整性。展示了一部分在功能上与Redis有重叠的数据库服务器和缓存服务器,从以下表中可以看出Redis与这些数据库及软件之间的区别。

一些数据库和缓存服务器的特性与功能

名称

类型

数据存储选项

查询类型

附加功能

Redis

使用内存存储(in-memory)的非关系数据库

字符串、列表、集合、散列表、有序集合

每种数据类型都有自己的专属命令,另外还有批量操作(bulk operation)和不完全(partial)的事务支持

发布与订阅,主从复制(master/slave replication),持久化,脚本(存储过程,stored procedure)

memcached

使用内存存储的键值缓存

键值之间的映射

创建命令、读取命令、更新命令、删除命令以及其他几个命令

为提升性能而设的多线程服务器

MySQL

关系数据库

每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图(view);支持空间(spatial)和第三方扩展

SELECT、INSERT、UPDATE、DELETE、函数、存储过程

支持ACID性质(需要使用InnoDB),主从复制和主主复制 (master/master replication)

PostgreSQL

关系数据库

每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图;支持空间和第三方扩展;支持可定制类型

SELECT、INSERT、UPDATE、DELETE、内置函数、自定义的存储过程

支持ACID性质,主从复制,由第三方支持的多主复制(multi-master replication)

MongoDB

使用硬盘存储(on-disk)的非关系文档存储

每个数据库可以包含多个表,每个表可以包含多个无schema(schema-less)的BSON文档

创建命令、读取命令、更新命令、删除命令、条件查询命令等

支持map-reduce操作,主从复制,分片,空间索引(spatial index)

4、Redis附加特性

  在使用类似Redis这样的内存数据库时,一个首先要考虑的问题就是“当服务器被关闭时,服务器存储的数据将何去何从呢?”Redis拥有两种不同形式的持久化方法,它们都可以用小而紧凑的格式将存储在内存中的数据写入硬盘:第一种持久化方法为时间点转储(point-in-time dump),转储操作既可以在“指定时间段内有指定数量的写操作执行”这一条件被满足时执行,又可以通过调用两条转储到硬盘(dump-to-disk)命令中的任何一条来执行;第二种持久化方法将所有修改了数据库的命令都写入一个只追加(append-only)文件里面,用户可以根据数据的重要程度,将只追加写入设置为从不同步(sync)、每秒同步一次或者每写入一个命令就同步一次。我们将在第4章中更加深入地讨论这些持久化选项。

  另外,尽管Redis的性能很好,但受限于Redis的内存存储设计,有时候只使用一台Redis服务器可能没有办法处理所有请求。因此,为了扩展Redis的读性能,并为Redis提供故障转移(failover)支持,Redis实现了主从复制特性:执行复制的从服务器会连接上主服务器,接收主服务器发送的整个数据库的初始副本(copy);之后主服务器执行的写命令,都会被发送给所有连接着的从服务器去执行,从而实时地更新从服务器的数据集。因为从服务器包含的数据会不断地进行更新,所以客户端可以向任意一个从服务器发送读请求,以此来避免对主服务器进行集中式的访问。我们将在第4章中更加深入地讨论Redis从服务器。

链接:http://www.epubit.com.cn/article/200

使用Redis的理由的更多相关文章

  1. 国内外三个不同领域巨头分享的Redis实战经验及使用场景

    Redis不是比较成熟的memcache或者Mysql的替代品,是对于大型互联网类应用在架构上很好的补充.现在有越来越多的应用也在纷纷基于Redis做架构的改造.首先简单公布一下Redis平台实际情况 ...

  2. redis对比其余数据库

    Redis属于常见的NoSQL数据库或者说非关系数据库:Redis不使用表,她的数据库也不会预定义或者强制去要求用户对Redis存储的不同数据进行关联. 常见数据库对比: 和高性能键值缓存服务器mem ...

  3. Redis应用场景-转载

    1.  MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的 ...

  4. Redis基础知识之—— 缓存应用场景

    转载原文:http://www.cnblogs.com/jinshengzhi/articles/5225718.html 一.MySql+Memcached架构的问题 Memcached采用客户端- ...

  5. (转)国内外三个不同领域巨头分享的Redis实战经验及使用场景

    随着应用对高性能需求的增加,NoSQL逐渐在各大名企的系统架构中生根发芽.这里我们将为大家分享社交巨头新浪微博.传媒巨头Viacom及图片分享领域佼佼者Pinterest带来的Redis实践,首先我们 ...

  6. <转>Redis 应用场景

    http://blog.csdn.net/hguisu/article/details/8836819 1.  MySql+Memcached 架构的问题 Memcached采用客户端-服务器的架构, ...

  7. Redis应用场景-整理

    1.  MySql+Memcached架构的问题 Memcached采用客户端-服务器的架构,客户端和服务器端的通讯使用自定义的协议标准,只要满足协议格式要求,客户端Library可以用任何语言实现. ...

  8. 学习Redis从这里开始

    本文主要内容 Redis与其他软件的相同之处和不同之处 Redis的用法 使用Python示例代码与Redis进行简单的互动 使用Redis解决实际问题 Redis是一个远程内存数据库,它不仅性能强劲 ...

  9. Redis初体验

    简介        Redis是一个速度非常快的非关系型数据库,它不仅性能强劲,而且还具有复制特性以及为解决问题而生的独一无二的数据模型.作为键值型数据库,Redis支持5中数据类型:字符串,列表,集 ...

随机推荐

  1. Gulp实战和原理解析

    Gulp实战和原理解析(以weui作为项目实例)http://i5ting.github.io/stuq-gulp/

  2. [三分]HDOJ 5531 Rebuild

    题意:给n个点,以这n个点为圆心画圆,使得所有的圆与其相邻的圆相切. 求n个圆最小的面积和. 分析:很容易想到确定了其中一个圆的半径之后,其他的圆的半径也能随之确定了. 画一画三个点的和四个点的,会发 ...

  3. Generic repository pattern and Unit of work with Entity framework

    原文 Generic repository pattern and Unit of work with Entity framework Repository pattern is an abstra ...

  4. Java API —— Pattern类

    正则表达式     写一个功能实现QQ号码的校验. import java.util.Scanner; public class RegexDemo01 { public static void ma ...

  5. android logcat里面AndroidRuntime FATAL EXCEPTION: main这个是什么问题啊。

    android logcat里面AndroidRuntime FATAL EXCEPTION: main这个是什么问题啊. http://zhidao.baidu.com/link?url=mUI11 ...

  6. qtp与selenium2的区别

    QTP:  我觉得qtp适合的人: 对编程不是很熟悉的 厌烦了手动的功能测试,想快速进入自动化行业的 公司想快速自动化项目,并且对价格或者对盗版无所谓的 vbs脚本语言易于上手,可以培训你对代码的兴趣 ...

  7. js问题总结

    .removeClass(" ") 移除一个css样式 $("#popUpBox i").removeClass("channel_icon" ...

  8. git中手动删除的文件如何在git中删除

    在日常开发中,我们可能或手动删除(delete键删除的)一些文件,然而我们本来应该是用git rm fileName命令删除的,但是现在我们手动删除了,那么要如何在git里面讲那些手动删除的文件删除呢 ...

  9. MySQL中REGEXP正则表达式使用大全

    REGEXP在mysql是用来执行正则表达式的一个函数 像php中的preg之类的函数了,regexp正则函数如果只是简单的查询使用like即可,但复杂的还是需要使用regexp了,下面我们来看看. ...

  10. HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)

    题目链接 题意:中文题意. 分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt>=0改成cnt>=2就行了,. 但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了, ...