Redis: REmote DIctionary Server


Redis is a key-value store NoSQL database。
性能高的原因在于大部分数据都被放在内存中,所以你可以将它看成是个内存数据库。


Problems:
key一定是String类型,怎么能够按照一定顺序,输出database中所有的keys?( keys * 不能保证有序) list all keys in some order?


Redis Documentation:
http://redis.io/documentation

Redis, from the Ground Up:
http://blog.mjrusso.com/2010/10/17/redis-from-the-ground-up.html#heading_toc_j_5
A whirlwind tour of the next bigthing in NoSQL data storage:
http://www.scribd.com/doc/33531219/Redis-Presentation



Install & Configuration & redis.conf:
安装redis server的正确方式参考 - Redis Quick Start:
http://redis.io/topics/quickstart
redis.conf 2.6版本说明:
https://raw.github.com/antirez/redis/2.6/redis.conf
其他参考资料:
Redis Administration - http://redis.io/topics/admin


Redis CLI:
# 连接至远程 redis server
$ redis-cli -h hostOfRemoteServer -p portOfRemoteServer




Redis Data Types:
http://redis.io/topics/data-types
A fifteen minute introduction to Redis data types:
http://redis.io/topics/data-types-intro
Redis是个key-value store,所有的redis里数据都是以key-value的形式存的,key是数据的唯一标示;key只能也只会是(Redis里的)String类型,即使你存的是int或其他,内部也是转成Strings存的,参见:
http://stackoverflow.com/questions/7973228/storing-integers-in-a-redis-ordered-set
但是有一点必须明确: redis中的String类型,其实是以字节数组的形式存的(Redis是C写的,使用C中的byte[]作为其String类型的存储形式),这保证了,redis的String类型是二进制安全(binary-safe)的,String本身是可以包含任意类型的数据的(因为任意的数据,在计算机世界里,都是可以转化为binary sequence的),比如一个图片,或者一个序列化之后的java对象(当然也可以是一个普通的字符串,如java中的String类型对象)。
在这里我们说的Redis Data Types,指的是key-value store中value的数据类型。Redis中key-value之value支持以下5种内置的数据类型:
String:如上所说,redis里的String类型是可以包含任意类型的数据的。
List:元素为String类型,并且有序的列表。redis的List数据类型是基于链表(Linked List)的,因为是基于链表的,所以其优点是插入和删除快,但缺点是定位和查找慢。
Set:元素为String类型,不可以重复,并且没有顺序的集合。
Sorted Set(zset):元素为String类型,不可以重复,但有顺序的集合。
Hash:value(redis key-value store之value)为Hash类型,其实就是value本身又是key-value pairs集合,内层键值对儿的数量最多可达2^32-1个。使用Hash类型,你可以实现类似下面的两层的key-value键值对儿映射关系:key:{subkey1:subvalue1;subkey2:subvalue2;...},其中任意的key、value都是String类型的;内层的二级key也不可以重复。 看的出来,其实redis的Hash类型,对应的就是java里的Map类型。通过Hash类型,你可以实现简单的两层的对象模型,如:
#为了存储userId为1000的用户的信息,我们使用Hash类型,以user:1000为key,将该用户的基本信息存入作为value的“多个二级内层key-value pairs”里:
HMSET user:1000 username antirez password P1pp0 age 34
可以看出,String类型是redis数据结构的核心,其他的list、set、zset、hash,其内部的元素(hash是内部key和内部value),都还(一定)是String类型的。
“key-value store structure”之value如果是list、set、zset、hash数据类型:
key在其声明使用之初被创建(如果尚未存在);
反之,如果因为删除等操作(list:lrem/lpop/rpop、set:srem、zset:zrem、hash:hdel等)致使这4种数据结构的元素数为0(hash是内部键值对儿数目为0),则对应的key也将自动从database中删除。


Redis数据模型设计:
通过对redis数据类型的分析,可以看的出来,Redis的所谓数据类型其实比较简单,远远不能应付复杂的业务数据模型场景。复杂业务数据模型,使用redis的话,可以在其“key-value store structure”的key上做文章,使key有业务含义,如下面的这些例子:
A case study: Design and implementation of a simple Twitter clone using only the Redis key-value store as database and PHP:
http://redis.io/topics/twitter-clone
引用
INCR global:nextUserId => 1000
SET uid:1000:username antirez
SET uid:1000:password p1pp0
We use the global:nextUserId key in order to always get an unique ID for every new user. Then we use this unique ID to populate all the other keys holding our user data. This is a Design Pattern with key-values stores! Keep it in mind.
http://blog.codingnow.com/2011/11/dev_note_2.html
http://doc.open-open.com/view/952fa31a0aa346ee9ccbe1d0b90632b6
Complex data structures Redis:
http://stackoverflow.com/questions/8810036/complex-data-structures-redis
Data modeling practices in Redis?
http://stackoverflow.com/questions/4908197/data-modeling-practices-in-redis
引用
Fundamentally Redis is a data structure server. How you structure your data depends almost entirely on what it is and how you need to access it。
Designing for Redis in my experience is more along the lines of "how simple is my structure?". Can you model your data via hash? If so, use the hash commands in Redis. Do you need to combine sets and key-values or hashes? Then do it the same in redis. Essentially, assume you were not using a database. If you did it entirely within your programming language and in memory, how would you model your data? Odds are that is how you'd do it in Redis - or close enough to figure the rest out.



Redis Server & instances & Databases:
一个运行中的Redis Server,就是一个Redis instance;每个Redis instance都和一个特定的host:port绑定;一个Redis instance中,可以有多个database;database的数目可以在redis.conf文件中指定,默认16个,使用0-based-index作为其唯一标示(默认的16个为0,1,...15);所有新的客户端连接,总是默认使用index为0的database(New connections always use DB 0)。
redis instance是单线程的,所以无法充分利用多核cpu的优势;如果你想充分利用多核的优势,你应该考虑启动多个redis instance。
引用
http://redis.io/topics/benchmarks
Redis is a single-threaded server. It is not designed to benefit from multiple CPU cores. People are supposed to launch several Redis instances to scale out on several cores if needed. It is not really fair to compare one single Redis instance to a multi-threaded data store.
Working with Multiple Databases:
http://rediscookbook.org/multiple_databases.html
database相关命令:SELECT MOVE(注意move是把当前db的指定key移动到指定的db!而不是拷贝!当前db中不再有该key!) FLUSHDB FLUSHALL。
使用什么命令可以显示当前db的index?
没有提供这样的命令!
move只可以将当前db的单个key移至指定的另外一个db,怎么实现拷贝,而不是移动那?更进一步,怎么将一个database中所有的keys,或符合一定条件的keys,一次性全部拷贝入另一个database中?


Lock & Transaction & multi/exec/watch/discard:
http://redis.io/topics/transactions
Redis instance 的 single-threaded的特性,保证了每个基本命令都已经是原子性(atomic)的;假使多个client对一个Redis instance的同一个key做读取/处理,则因为redis instance是单线程的原因,当多个clienit出现了race conditions时,Redis instance是根据先到先处理的原则,其他排队等待(可设置为直接丢弃)。
但是,很多场景下,我们还是需要transaction,来保证让多个命令的组合被作为一个原子操作来执行。redis提供两种简单的锁机制:
1 multi & exec,这是一个悲观锁,被锁住的key将会无法再被其他client读取或写入;multi命令表征事务的开始,exec表示作为一个原子操作来执行multi和exec之间的命令组合;另外需要注意,与rdbms中事务不同的是,redis的锁机制下,如果事务中的某条命令执行失败,事务是不会回滚,只是将失败的命令丢弃掉,事务中的其他命令还是会被执行。
2 使用watch实现“Check and Set”(CAS) transactions(乐观锁):如果被watch的key在exec之前被修改了(可能是被其他的licents),则当前client的multi/exec间的事务被aborted。
引用
http://blog.mjrusso.com/2010/10/17/redis-from-the-ground-up.html#heading_toc_j_4
Redis transactions can be used to make a series of commands atomic. (Every Redis command is already atomic; transactions, however, allow us to combine a number of commands into a single atomic unit.)
MULTI delineates the start of a transaction block; EXEC is responsible for actually running the transaction (i.e., executing all commands between the MULTI and the EXEC, with no other commands executed in-between).
There is an important caveat: because the commands are queued and then executed sequentially (all at once, as if they were a single unit), it is not possible to read a value while a transaction is being executed and to then subsequently use this value at any point during the course of the same transaction.
To address this restriction, Redis supports “Check and Set” (CAS) transactions. CAS is available via the WATCH command.



serialization & deserialization(java为例):



Commands:
http://redis.io/commands#
引用
set
get
setnx:SET-if-not-exists
del
INCR: atomically increment a number stored at a given key
EXPIRE: be sure a key-value pairs only exist for a certain length of time
格式:expire key secondNum 如:
TTL:time to live,test how long a key will exist。The -1 for the TTL of a particular key means that it will never expire. Note that if you SET a key, its TTL will reset.

使用list(A list is a series of ordered values)作为key的相关命令:
RPUSH puts the new value at the end of the list.
LPUSH puts the new value at the start of the list.
LLEN returns the current length of the list.
LRANGE gives a subset of the list. It takes the index of the first element you want to retrieve as its first parameter and the index of the last element you want to retrieve as its second parameter. A value of -1 for the second parameter means to retrieve all elements in the list.
LPOP removes the first element from the list and returns it.
RPOP removes the last element from the list and returns it.

使用set(each element in a set may only appear once)作为key的相关命令:
SADD adds the given value to the set.
SREM removes the given value from the set.
SISMEMBER tests if the given value is in the set.
SMEMBERS eturns a list of all the members of this set.
SUNION combines two or more sets and returns the list of all elements.
sorted set相关:
ZADD
ZRANGE




Redis容错及灾难恢复:
一 Redis Persistence:
引用
http://redis.io/topics/persistence
redis提供两种持久化机制:
RDB:这是默认的持久化策略,默认的rdb文件名为dump.rdb。.rdb文件格式参考:
https://github.com/sripathikrishnan/redis-rdb-tools/wiki/Redis-RDB-Dump-File-Format
引用
Redis *.rdb file is a binary representation of the in-memory store. This binary file is sufficient to completely restore Redis’ state
AOF: Append Only File。默认是关闭的,你可以通过将redis.conf中的“appendonly no”改为“appendonly yes”(或命令行下执行: config set appendonly yes)来开启该持久化机制;开启后aof文件的默认名字为appendonly.aof
二 Redis master-slave Replication:
http://redis.io/topics/replication


srcs:
Redis几个认识误区:
http://timyang.net/data/redis-misunderstanding/
redis + java + nohm(node.js) 的一个例子:
http://www.ibm.com/developerworks/java/library/j-javadev2-22/index.html

猜你喜欢

转载自wuaner.iteye.com/blog/1718335
今日推荐