redis大数据
1. 华为大数据平台如何查看redis集群端口
华为大数据平台redis集群端口
注:ip为安装redis的那台服务器(集群中的其中一台)的ip,password为redis的密码
集群相关信息查看
1.集群状态
redis-cli -h ip -p 9379 -a password cluster info
2.集群节点信息
redis-cli -h ip -p 9379 -a password cluster nodes
3.节点内存、cpu、key数量等信息(每个节点都需查看)
redis-cli -h ip -p 9379 -a password info
2. Spark和Redis结合使用到底有多大的性能提升呢45倍
Spark代表着下一代大数据处理技术,并且,借着开源算法和计算节点集群分布回式处理,Spark和Hadoop在执行答的方式和速度已经远远的超过传统单节点的技术架构。但Spark利用内存进行数据处理,这让Spark的处理速度超过基于磁盘的Hadoop 100x 倍。
但Spark和内存数据库Redis结合后可显著的提高Spark运行任务的性能,这源于Redis优秀的数据结构和执行过程,从而减小数据处理的复杂性和开销。Spark通过一个Redis连接器可以访问Redis的数据和API,加速Spark处理数据。
Spark和Redis结合使用到底有多大的性能提升呢?结合这两者来处理时序数据时可以提高46倍以上——而不是提高百分之四十五。
3. redis 数据达到多少存磁盘
IO:输入输出。
从内存读取数据叫输出,将数据写入内存叫输入。
大数据IO就是指在磁盘与内存之间传输大量数据的意思咯。只不过因为数据太大内存容纳不下需要进行多次部分写入。
数据在磁盘上是无法完成查找的,要么被调入内存,要么有磁盘数据的索引(索引调入内存)。计算机所有操作都是在内存中进行的,磁盘是外设。
4. redis大数据并发有哪些测试点
Libevent。和Memcached不同,Redis并没有选择libevent。Libevent为了迎合通用性造成代码庞大(目前内Redis代码还不到libevent的1/3)及牺容牲了在特定平台的不少性能。Redis用libevent中两个文件修改实现了自己的epoll event loop(4)。 业界不少开发者
5. 大量数据能缓存到redis里面吗
不适合引子:
在大数据时代,总希望存在一个Key-value存储机制,像HashMap一样在内存中处理大量(千万数量级)的key-value对,以便提高数据查找、修改速度。
所以,我们会想到,Memcached和Redis这两个NoSQL数据库(严格来讲二者都不可以算作数据库)。
1、Memcached是一个cache机制,当内存不足时会采用LRU机制,替换出陈旧数据,因此他不能保证我们的数据像在HashMap中一样不丢失,且没有数据持久化机制;
2、Redis克服了这一缺点,采取磁盘存储机制实现数据持久化。但是,当数据量达到1千万左右时,由于内存中不能存储如此大量数目的数据,频繁同磁盘进行数据交换,导致数据查询、存储性能的急剧下降,将导致服务不可用。
结论:当前还没有好的产品可以实现key-value保证数据完整性,千万级条数量级的,高效存储和查询支持产品。
附录一:如下是转自其它网友的测试数据:
附录二:memcached 和redis的比较,和各自用途
附录一:
从图中可以猜测到还会有Redis 2.2.1 的测试,相同的测试环境,1K的数据量,使用ServiceStack.Redis客户端进行如下测试:
1) Set操作
2) Get操作
3) Del操作
每一套测试分别使用三个配置进行测试:
1) 绿色线条的是开启Dump方式的持久化,5分钟持久化一次
2) 蓝色线条是开启AOF方式的持久化,每秒写入磁盘一次
3) 红色线条是关闭任何的持久化方式
对于每一个配置都使用相同的其他配置:
1) 开启VM 最大内存10GB(128字节一
6. 总结redis在节省内存开销方面做过哪些设计
因为是拿 Python 测试的,所以可能对其他语言并不完全适用。
使用的测试数据是特定的,可能对更小或更大的数据并不完全适用。
测试结果就不列出了,直接说结论吧。
最差的存储方式就是用一个 hash 来存储一个实体(即一条记录)。时间上比其他方案慢 1 ~ 2 倍,空间占用较大。
更重要的是拿出来的字段类型是字符串,还得自己转换类型。
唯一的好处就是可以单独操作一个字段。
使用 string 类型来存储也是不推荐的,不过稍好于前一种方式。在单个实体较小时,会暴露出 key 占用内存较多的缺点。
用一个 hash 来存储一个类型的所有实体(即一张表),在实现上比较简单,内存占用尚可。
用多个 hash 来存储一个类型的所有实体(即分表),在实现上稍微复杂点,但占用的内存最小。
如果单个字段值较小(缺省值是 64 字节),单个 hash 存储的字段数不多(缺省值是 512 个)时,会采用 hash zipmap 来存储,内存占用会显著减小。
单个 hash 存储的字段数建议为 2 的次方,例如 1024。略微超过这个值,会导致内存占用和延迟时间都增加。
Instagram 的工程师认为,使用 hash zipmap 时,最佳的字段数为 1000 左右。不过据我测试,基本都是随字段数增加而变慢,而内存占用从 128 直到 1024 的变化基本可以忽略。
存储为 JSON 格式是种不错的选择。对包含中文的内容来说,设置 ensure_ascii=False 可以节省大量内存。
ujson 比 json 性能好很多,后者在设置 ensure_ascii=False 后性能急剧下降。
cPickle 比 ujson 的性能要差,不过支持更多类型(如 datetime)。
MessagePack 比 ujson 有一点不太明显的性能优势,不过丧失了可读性,且取回 unicode 需要自己 decode。
号称比 Protocol Buffer 快 4 倍应该可以无视了,至少其 Python 库没有明显优势。
使用 zlib 压缩可以节省更多内存,不过性能变慢 1 ~ 2 倍。
看这个测试结果,感觉还不如用 MongoDB 省事……
7. 如何取出大数据量的 redis hash 结构的数据并遍历导出
就看你的数据量大小了,如果太大,却是不好遍历,如果有规则的key值的话,倒是可以利用分页的方式来处理,如果没有规律的话,只有用keys*来取了,或者是通过keysa*;keysz*;keys1*;keys0*等通配符的方式来顺序的读取,读取时要把内存分配的大一些,不然容易溢出
8. 你所了解的大数据,是真正的大数据吗
什么是大数据
大数据是指无法在一定时间内用常规软件工具对其内容进行抓取、管理和处理的数据集合。大数据技术,是指从各种各样类型的数据中,快速获得有价值信息的能力。适用于大数据的技术,包括大规模并行处理(MPP)数据库,数据挖掘电网,分布式文件系统,分布式数据库,云计算平台,互联网,和可扩展的存储系统。
大数据时代存储所面对的问题
随着大数据应用的爆发性增长,它已经衍生出了自己独特的架构,而且也直接推动了存储、网络以及计算技术的发展。毕竟处理大数据这种特殊的需求是一个新的挑战。硬件的发展最终还是由软件需求推动的,就这个例子来说,我们很明显的看到大数据分析应用需求正在影响着数据存储基础设施的发展。
从另一方面看,这一变化对存储厂商和其他IT基础设施厂商未尝不是一个机会。随着结构化数据和非结构化数据量的持续增长,以及分析数据来源的多样化,此前存储系统的设计已经无法满足大数据应用的需要。存储厂商已经意识到这一点,他们开始修改基于块和文件的存储系统的架构设计以适应这些新的要求。在这里,我们会讨论哪些与大数据存储基础设施相关的属性,看看它们如何迎接大数据的挑战。
容量问题
这里所说的“大容量”通常可达到PB级的数据规模,因此,海量数据存储系统也一定要有相应等级的扩展能力。与此同时,存储系统的扩展一定要简便,可以通过增加模块或磁盘柜来增加容量,甚至不需要停机。基于这样的需求,客户现在越来越青睐Scale-out架构的存储。Scale-out集群结构的特点是每个节点除了具有一定的存储容量之外,内部还具备数据处理能力以及互联设备,与传统存储系统的烟囱式架构完全不同,Scale-out架构可以实现无缝平滑的扩展,避免存储孤岛。
“大数据”应用除了数据规模巨大之外,还意味着拥有庞大的文件数量。因此如何管理文件系统层累积的元数据是一个难题,处理不当的话会影响到系统的扩展能力和性能,而传统的NAS系统就存在这一瓶颈。所幸的是,基于对象的存储架构就不存在这个问题,它可以在一个系统中管理十亿级别的文件数量,而且还不会像传统存储一样遭遇元数据管理的困扰。基于对象的存储系统还具有广域扩展能力,可以在多个不同的地点部署并组成一个跨区域的大型存储基础架构。
延迟问题
“大数据”应用还存在实时性的问题。特别是涉及到与网上交易或者金融类相关的应用。举个例子来说,网络成衣销售行业的在线广告推广服务需要实时的对客户的浏览记录进行分析,并准确的进行广告投放。这就要求存储系统在必须能够支持上述特性同时保持较高的响应速度,因为响应延迟的结果是系统会推送“过期”的广告内容给客户。这种场景下,Scale-out架构的存储系统就可以发挥出优势,因为它的每一个节点都具有处理和互联组件,在增加容量的同时处理能力也可以同步增长。而基于对象的存储系统则能够支持并发的数据流,从而进一步提高数据吞吐量。
有很多“大数据”应用环境需要较高的IOPS性能(IOPS (Input/Output Operations Per Second),即每秒进行读写(I/O)操作的次数,多用于数据库等场合,衡量随机访问的性能),比如HPC高性能计算。此外,服务器虚拟化的普及也导致了对高IOPS的需求,正如它改变了传统IT环境一样。为了迎接这些挑战,各种模式的固态存储设备应运而生,小到简单的在服务器内部做高速缓存,大到全固态介质的可扩展存储系统等等都在蓬勃发展。
并发访问一旦企业认识到大数据分析应用的潜在价值,他们就会将更多的数据集纳入系统进行比较,同时让更多的人分享并使用这些数据。为了创造更多的商业价值,企业往往会综合分析那些来自不同平台下的多种数据对象。包括全局文件系统在内的存储基础设施就能够帮助用户解决数据访问的问题,全局文件系统允许多个主机上的多个用户并发访问文件数据,而这些数据则可能存储在多个地点的多种不同类型的存储设备上。
安全问题
某些特殊行业的应用,比如金融数据、医疗信息以及政府情报等都有自己的安全标准和保密性需求。虽然对于IT管理者来说这些并没有什么不同,而且都是必须遵从的,但是,大数据分析往往需要多类数据相互参考,而在过去并不会有这种数据混合访问的情况,因此大数据应用也催生出一些新的、需要考虑的安全性问题。
成本问题
“大”,也可能意味着代价不菲。而对于那些正在使用大数据环境的企业来说,成本控制是关键的问题。想控制成本,就意味着我们要让每一台设备都实现更高的“效率”,同时还要减少那些昂贵的部件。目前,像重复数据删除等技术已经进入到主存储市场,而且现在还可以处理更多的数据类型,这都可以为大数据存储应用带来更多的价值,提升存储效率。在数据量不断增长的环境中,通过减少后端存储的消耗,哪怕只是降低几个百分点,都能够获得明显的投资回报。此外,自动精简配置、快照和克隆技术的使用也可以提升存储的效率。
很多大数据存储系统都包括归档组件,尤其对那些需要分析历史数据或需要长期保存数据的机构来说,归档设备必不可少。从单位容量存储成本的角度看,磁带仍然是最经济的存储介质,事实上,在许多企业中,使用支持TB级大容量磁带的归档系统仍然是事实上的标准和惯例。
对成本控制影响最大的因素是那些商业化的硬件设备。因此,很多初次进入这一领域的用户以及那些应用规模最大的用户都会定制他们自己的“硬件平台”而不是用现成的商业产品,这一举措可以用来平衡他们在业务扩展过程中的成本控制战略。为了适应这一需求,现在越来越多的存储产品都提供纯软件的形式,可以直接安装在用户已有的、通用的或者现成的硬件设备上。此外,很多存储软件公司还在销售以软件产品为核心的软硬一体化装置,或者与硬件厂商结盟,推出合作型产品。
数据的积累
许多大数据应用都会涉及到法规遵从问题,这些法规通常要求数据要保存几年或者几十年。比如医疗信息通常是为了保证患者的生命安全,而财务信息通常要保存7年。而有些使用大数据存储的用户却希望数据能够保存更长的时间,因为任何数据都是历史记录的一部分,而且数据的分析大都是基于时间段进行的。要实现长期的数据保存,就要求存储厂商开发出能够持续进行数据一致性检测的功能以及其他保证长期高可用的特性。同时还要实现数据直接在原位更新的功能需求。
灵活性
大数据存储系统的基础设施规模通常都很大,因此必须经过仔细设计,才能保证存储系统的灵活性,使其能够随着应用分析软件一起扩容及扩展。在大数据存储环境中,已经没有必要再做数据迁移了,因为数据会同时保存在多个部署站点。一个大型的数据存储基础设施一旦开始投入使用,就很难再调整了,因此它必须能够适应各种不同的应用类型和数据场景。
应用感知
最早一批使用大数据的用户已经开发出了一些针对应用的定制的基础设施,比如针对政府项目开发的系统,还有大型互联网服务商创造的专用服务器等。在主流存储系统领域,应用感知技术的使用越来越普遍,它也是改善系统效率和性能的重要手段,所以,应用感知技术也应该用在大数据存储环境里。
小用户怎么办?
依赖大数据的不仅仅是那些特殊的大型用户群体,作为一种商业需求,小型企业未来也一定会应用到大数据。我们看到,有些存储厂商已经在开发一些小型的“大数据”存储系统,主要吸引那些对成本比较敏感的用户。
9. 有哪些大数据服务架构 hadoop redis hbase spark hive storm
大数据分很多块,包括内存数据库,mpp,hadoop,实时流处理,数据抽取转换,可视化等。每一块查一下就知道了,内容太多
10. redis这些内存消耗数据怎么看呢,主要看哪个说明内存比较大了
Redis常用数据类型
Redis最为常用的数据类型主要有以下五种:
String
Hash
List
Set
Sorted set
在具体描述这几种数据类型之前,我们先通过一张图了解下Redis内部内存管理中是如何描述这些不同数据类型的:
首先Redis内部使用一个redisObject对象来表示所有的key和value,redisObject最主要的信息如上图所示:type代表一个value对象具体是何种数据类型,encoding是不同数据类型在redis内部的存储方式,比如:type=string代表value存储的是一个普通字符串,那么对应的encoding可以是raw或者是int,如果是int则代表实际redis内部是按数值型类存储和表示这个字符串的,当然前提是这个字符串本身可以用数值表示,比如:“123” “456”这样的字符串。
这里需要特殊说明一下vm字段,只有打开了Redis的虚拟内存功能,此字段才会真正的分配内存,该功能默认是关闭状态的,该功能会在后面具体描述。通过上图我们可以发现Redis使用redisObject来表示所有的key/value数据是比较浪费内存的,当然这些内存管理成本的付出主要也是为了给Redis不同数据类型提供一个统一的管理接口,实际作者也提供了多种方法帮助我们尽量节省内存使用,我们随后会具体讨论。
下面我们先来逐一的分析下这五种数据类型的使用和内部实现方式:
String
常用命令:
set,get,decr,incr,mget 等。
应用场景:
String是最常用的一种数据类型,普通的key/value存储都可以归为此类,这里就不所做解释了。
实现方式:
String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。
Hash
常用命令:
hget,hset,hgetall 等。
应用场景:
我们简单举个实例来描述下Hash的应用场景,比如我们要存储一个用户信息对象数据,包含以下信息:
用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储,主要有以下2种存储方式:
常用内存优化手段与参数
通过我们上面的一些实现上的分析可以看出redis实际上的内存管理成本非常高,即占用了过多的内存,作者对这点也非常清楚,所以提供了一系列的参数和手段来控制和节省内存,我们分别来讨论下。
首先最重要的一点是不要开启Redis的VM选项,即虚拟内存功能,这个本来是作为Redis存储超出物理内存数据的一种数据在内存与磁盘换入换出的一个持久化策略,但是其内存管理成本也非常的高,并且我们后续会分析此种持久化策略并不成熟,所以要关闭VM功能,请检查你的redis.conf文件中 vm-enabled 为 no。
其次最好设置下redis.conf中的maxmemory选项,该选项是告诉Redis当使用了多少物理内存后就开始拒绝后续的写入请求,该参数能很好的保护好你的Redis不会因为使用了过多的物理内存而导致swap,最终严重影响性能甚至崩溃。
另外Redis为不同数据类型分别提供了一组参数来控制内存使用,我们在前面详细分析过Redis Hash是value内部为一个HashMap,如果该Map的成员数比较少,则会采用类似一维线性的紧凑格式来存储该Map, 即省去了大量指针的内存开销,这个参数控制对应在redis.conf配置文件中下面2项:
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
hash-max-zipmap-entries
含义是当value这个Map内部不超过多少个成员时会采用线性紧凑格式存储,默认是64,即value内部有64个以下的成员就是使用线性紧凑存储,超过该值自动转成真正的HashMap。
hash-max-zipmap-value 含义是当 value这个Map内部的每个成员值长度不超过多少字节就会采用线性紧凑存储来节省空间。
以上2个条件任意一个条件超过设置值都会转换成真正的HashMap,也就不会再节省内存了,那么这个值是不是设置的越大越好呢,答案当然是否定的,HashMap的优势就是查找和操作的时间复杂度都是O(1)的,而放弃Hash采用一维存储则是O(n)的时间复杂度,如果
成员数量很少,则影响不大,否则会严重影响性能,所以要权衡好这个值的设置,总体上还是最根本的时间成本和空间成本上的权衡。
同样类似的参数还有:
list-max-ziplist-entries 512
说明:list数据类型多少节点以下会采用去指针的紧凑存储格式。
list-max-ziplist-value 64
说明:list数据类型节点值大小小于多少字节会采用紧凑存储格式。
set-max-intset-entries 512
说明:set数据类型内部数据如果全部是数值型,且包含多少节点以下会采用紧凑格式存储。
最后想说的是Redis内部实现没有对内存分配方面做过多的优化,在一定程度上会存在内存碎片,不过大多数情况下这个不会成为Redis的性能瓶颈,不过如果在Redis内部存储的大部分数据是数值型的话,Redis内部采用了一个shared integer的方式来省去分配内存的开销,即在系统启动时先分配一个从1~n 那么多个数值对象放在一个池子中,如果存储的数据恰好是这个数值范围内的数据,则直接从池子里取出该对象,并且通过引用计数的方式来共享,这样在系统存储了大量数值下,也能一定程度上节省内存并且提高性能,这个参数值n的设置需要修改源代码中的一行宏定义REDIS_SHARED_INTEGERS,该值默认是10000,可以根据自己的需要进行修改,修改后重新编译就可以了。
Redis的持久化机制
Redis由于支持非常丰富的内存数据结构类型,如何把这些复杂的内存组织方式持久化到磁盘上是一个难题,所以Redis的持久化方式与传统数据库的方式有比较多的差别,Redis一共支持四种持久化方式,分别是:
在设计思路上,前两种是基于全部数据都在内存中,即小数据量下提供磁盘落地功能,而后两种方式则是作者在尝试存储数据超过物理内存时,即大数据量的数据存储,截止到本文,后两种持久化方式仍然是在实验阶段,并且vm方式基本已经被作者放弃,所以实际能在生产环境用的只有前两种,换句话说Redis目前还只能作为小数据量存储(全部数据能够加载在内存中),海量数据存储方面并不是Redis所擅长的领域。下面分别介绍下这几种持久化方式:
定时快照方式(snapshot):
该持久化方式实际是在Redis内部一个定时器事件,每隔固定时间去检查当前数据发生的改变次数与时间是否满足配置的持久化触发的条件,如果满足则通过操作系统fork调用来创建出一个子进程,这个子进程默认会与父进程共享相同的地址空间,这时就可以通过子进程来遍历整个内存来进行存储操作,而主进程则仍然可以提供服务,当有写入时由操作系统按照内存页(page)为单位来进行-on-write保证父子进程之间不会互相影响。
该持久化的主要缺点是定时快照只是代表一段时间内的内存映像,所以系统重启会丢失上次快照与重启之间所有的数据。
基于语句追加方式(aof):
aof方式实际类似mysql的基于语句的binlog方式,即每条会使Redis内存数据发生改变的命令都会追加到一个log文件中,也就是说这个log文件就是Redis的持久化数据。
aof的方式的主要缺点是追加log文件可能导致体积过大,当系统重启恢复数据时如果是aof的方式则加载数据会非常慢,几十G的数据可能需要几小时才能加载完,当然这个耗时并不是因为磁盘文件读取速度慢,而是由于读取的所有命令都要在内存中执行一遍。另外由于每条命令都要写log,所以使用aof的方式,Redis的读写性能也会有所下降。
虚拟内存方式:
虚拟内存方式是Redis来进行用户空间的数据换入换出的一个策略,此种方式在实现的效果上比较差,主要问题是代码复杂,重启慢,复制慢等等,目前已经被作者放弃。
diskstore方式:
diskstore方式是作者放弃了虚拟内存方式后选择的一种新的实现方式,也就是传统的B-tree的方式,目前仍在实验阶段,后续是否可用我们可以拭目以待。
Redis持久化磁盘IO方式及其带来的问题
有Redis线上运维经验的人会发现Redis在物理内存使用比较多,但还没有超过实际物理内存总容量时就会发生不稳定甚至崩溃的问题,有人认为是基于快照方式持久化的fork系统调用造成内存占用加倍而导致的,这种观点是不准确的,因为fork 调用的-on-write机制是基于操作系统页这个单位的,也就是只有有写入的脏页会被复制,但是一般你的系统不会在短时间内所有的页都发生了写入而导致复制,那么是什么原因导致Redis崩溃的呢?
答案是Redis的持久化使用了Buffer IO造成的,所谓Buffer IO是指Redis对持久化文件的写入和读取操作都会使用物理内存的Page Cache,而大多数数据库系统会使用Direct IO来绕过这层Page Cache并自行维护一个数据的Cache,而当Redis的持久化文件过大(尤其是快照文件),并对其进行读写时,磁盘文件中的数据都会被加载到物理内存中作为操作系统对该文件的一层Cache,而这层Cache的数据与Redis内存中管理的数据实际是重复存储的,虽然内核在物理内存紧张时会做Page Cache的剔除工作,但内核很可能认为某块Page Cache更重要,而让你的进程开始Swap ,这时你的系统就会开始出现不稳定或者崩溃了。我们的经验是当你的Redis物理内存使用超过内存总容量的3/5时就会开始比较危险了。
定时快照方式(snapshot)
基于语句追加文件的方式(aof)
虚拟内存(vm)
Diskstore方式
第一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。
第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的。
那么Redis提供的Hash很好的解决了这个问题,Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口,如下图:
也就是说,Key仍然是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部Map的Key(Redis里称内部Map的key为field), 也就是通过 key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。很好的解决了问题。
这里同时需要注意,Redis提供了接口(hgetall)可以直接取到全部的属性数据,但是如果内部Map的成员很多,那么涉及到遍历整个内部Map的操作,由于Redis单线程模型的缘故,这个遍历操作可能会比较耗时,而另其它客户端的请求完全不响应,这点需要格外注意。
实现方式:
上面已经说到Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。
List
常用命令:
lpush,rpush,lpop,rpop,lrange等。
应用场景:
Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现,比较好理解,这里不再重复。
实现方式:
Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。
Set
常用命令:
sadd,spop,smembers,sunion 等。
应用场景:
Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
实现方式:
set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。
Sorted set
常用命令:
zadd,zrange,zrem,zcard等
使用场景:
Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。
实现方式:
Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。