您的位置:首页 > 数据库 > Redis

redis学习(一)

2016-04-19 23:50 375 查看
一.redis简介
Redis是基于内存、可持久化的日志型、key-value高性能存储系统。关键字(Keys)是用来标识数据块。值(Values)是关联于关键字的实际值,可以是任何东西。有时候你会存储字符串,有时候是整数,还有时候你会存储序列化对象(使用JSON、XML等)。在大多数情况下,Redis会把值看做是一个字节序列,而不会关注它们实质上是什么。

Redis支持存储的value类型:string(字符串)、hash(散列)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集等更多操作,而且这些操作都是原子性的。redis支持不同方式的排序。为了保证效率,数据都是缓存在内存中。redis会周期性的把更新的数据写入磁盘或者把操作写入追加的记录文件,并在此基础上实现了master-slaver(主从)同步。

Redis主要用于缓存、数据持久化、消息队列等,数据不是一直存储在内存中,这是不同于memcached的地方。Redis只缓存所有的Key的信息,如果内存的使用量超过某一阈值,将触发swap的操作,会将部分key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以保持超过其机器本身内存大小的数据。当 从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方,这就存在一个I/O线程池的问题,默认会发生阻塞的情况。所以,Redis使用的最佳方式是全部数据都在内存中。

二.redis支持的数据结构
1.字符串(Strings)

我们已经看到了一个常见的字符串使用案例,即通过关键字存储对象的实例。有时候,你会频繁地用到这类操作:

set users:leto "{name: leto, planet: dune, likes: [spice]}"


Redis还有一些常用的操作。例如,
strlen <key>
能用来获取一个关键字对应值的长度;
getrange <key> <start> <end>
将返回指定范围内的关键字对应值;
append <key> <value>
会将value附加到已存在的关键字对应值中(如果该关键字并不存在,则会创建一个新的关键字-值对)。

2.散列(Hashes)

散列数据结构很像字符串数据结构。两者显著的区别在于,散列数据结构提供了一个额外的间接层:一个域(Field)。因此,散列数据结构中的
set
get
是:

hset users:goku powerlevel 9000
hget users:goku powerlevel

相关的操作还包括在同一时间设置多个域、同一时间获取多个域、获取所有的域和值、列出所有的域或者删除指定的一个域:

hmset users:goku race saiyan age 737
hmget users:goku race powerlevel
hgetall users:goku
hkeys users:goku
hdel users:goku age

如你所见,散列数据结构比普通的字符串数据结构具有更多的可操作性。我们可以使用一个散列数据结构去获得更精确的描述,是存储一个用户,而不是一个序列化对象。从而得到的好处是能够提取、更新和删除具体的数据片段,而不必去获取或写入整个值。

3.列表(Lists)

对于一个给定的关键字,列表数据结构让你可以存储和处理一组值。你可以添加一个值到列表里、获取列表的第一个值或最后一个值以及用给定的索引来处理值。列表数据结构维护了值的顺序,提供了基于索引的高效操作。为了跟踪在网站里注册的最新用户,我们可以维护一个
newusers
的列表:

lpush newusers goku
ltrim newusers 0 50

(译注:
ltrim
命令的具体构成是
LTRIM Key start stop
。要理解
ltrim
命令,首先要明白Key所存储的值是一个列表,理论上列表可以存放任意个值。对于指定的列表,根据所提供的两个范围参数start和stop,
ltrim
命令会将指定范围外的值都删除掉,只留下范围内的值。)


4.集合(Sets)

集合数据结构常常被用来存储只能唯一存在的值,并提供了许多的基于集合的操作,例如并集。集合数据结构没有对值进行排序,但是其提供了高效的基于值的操作。使用集合数据结构的典型用例是朋友名单的实现:

sadd friends:leto ghanima paul chani jessica
sadd friends:duncan paul jessica alia

不管一个用户有多少个朋友,我们都能高效地(O(1)时间复杂度)识别出用户X是不是用户Y的朋友:

sismember friends:leto jessica
sismember friends:leto vladimir

而且,我们可以查看两个或更多的人是不是有共同的朋友:

sinter friends:leto friends:duncan

甚至可以在一个新的关键字里存储结果:

sinterstore friends:leto_duncan friends:leto friends:duncan


5.分类集合(Sorted Sets)
分类集合数据结构就类似于集合数据结构,主要区分是标记(score)的概念。

标记提供了排序(sorting)和秩划分(ranking)的功能。如果我们想要一个秩分类的朋友名单,可以这样做:

zadd friends:duncan 70 ghanima 95 paul 95 chani 75 jessica 1 vladimir

对于
duncan
的朋友,要怎样计算出标记(score)为90或更高的人数?

zcount friends:duncan 90 100

如何获取
chani
在名单里的秩(rank)?

zrevrank friends:duncan chani

(译注:
zrank
命令的具体构成是
ZRANK Key menber
,要知道Key存储的Sorted Set默认是根据Score对各个menber进行升序的排列,该命令就是用来获取menber在该排列里的次序,这就是所谓的秩。)


我们使用了
zrevrank
命令而不是
zrank
命令,这是因为Redis的默认排序是从低到高,但是在这个例子里我们的秩划分是从高到低。对于分类集合数据结构,最常见的应用案例是用来实现排行榜系统。

三.redis应用背景
1.性能需求, 随着读操作的量的上升需要解决,经历的过程有: 数据库读写分离(M/S)–>数据库使用多个Slave–>增加Cache (memcache)–>转到Redis

2.解决写的问题: 水平拆分,对表的拆分,将有的用户放在这个表,有的用户放在另外一个表;

3.可靠性需求 :Cache的"雪崩"问题让人纠结,Cache面临着快速恢复的挑战;
4.开发成本需求 :Cache和DB的一致性维护成本越来越高(先清理DB, 再清理缓存, 不行啊, 太慢了!)
5.开发需要跟上不断涌入的产品需求 :硬件成本最贵的就是数据库层面的机器,基本上比前端的机器要贵几倍,主要是IO密集型,很耗硬件;
6.维护性复杂 :一致性维护成本越来越高;
7.BerkeleyDB使用B树,会一直写新的,内部不会有文件重新组织;这样会导致文件越来越大;大的时候需要进行文件归档,归档的操作要定期做;
这样,就需要有一定的down time;

四.redis性能特点

1.丰富的数据支持;

2.主要用来存储少量数据,支持超过 100K+ 每秒的读写频率;
3.Redis支持数据的备份,即master-slave模式的数据备份(主从复制);
4.redis支持原子操作,
5.使用分布式redis实现海量数据存储,保证数据一致性;
6.丰富的特性:Redis还支持 publish/subscribe, 通知, key 过期等特性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: