概述
1、Redis简介
Redis是一个key-value类型的内存数据库,每一个key都与一个value关联,使得Redis与其他key-value数据库不同是因为在Redis中的每一个value都有一个类型(type),目前在Redis中支持5中数据类型:String、List、Set、ZSet和Hash。每一种类型决定了可以赋予其上的操作(这些操作成为命令command)。比如你可以使用LPUSH或RPUSH命令在O(1)时间对一个list添加一个元素,然后你可以使用LRANGE命令得到list中的一部分元素或使用LTRIM对该list进行trim操作。集合set操作也是很灵活的,你可以从set(无序的String的集合)中add或remove元素,还可以进行交集、合集和差集运算。每一个command都是服务端自动的操作。
Redis性能上和memcached一样快但提供了更多的特性。和memcached一样,Redis支持对key设置失效时间,因此当设定的时间过后会被自动删除。
1.1、Redis特性
Ø 速度快
Redis使用标准C编写实现,而且将所有数据加载到内存中,所以速度非常快。官方提供的数据表明,在一个普通的Linux机器上,Redis读写速度分别达到81000/s和110000/s。
Ø 持久化
由于所有数据保持在内存中(2.0版本开始可以只将部分数据的value放在内存,见“虚拟内存”),所以对数据的更新将异步地保存到磁盘上,Redis提供了一些策略来保存数据,比如根据时间或更新次数。
Ø 数据结构
可以将Redis看做“数据结构服务器”。目前,Redis支持5种数据结构。
Ø 自动操作
Redis对不同数据类型的操作是自动的,因此设置或增加key值,从一个集合中增加或删除一个元素都能安全的操作。
Ø 支持多种语言
Redis支持多种语言,诸如Ruby, Python, Twisted Python, PHP, Erlang, Tcl, Perl, Lua, Java, Scala, Clojure等。对Java的支持,包括两个。一是JDBC-Redis,是使用JDBC连接Redis数据库的驱动。这个项目的目标并不是完全实现JDBC规范,因为Redis不是关系型数据库,但给Java开发人员提供了一个像操作关系数据库一样操作Redis数据库的接口。
另一个是JRedis,是使用Redis作为数据库开发Java程序的开发包,主要提供了对数据结构的操作。
Ø 主-从复制
Redis支持简单而快速的主-从复制。官方提供了一个数据,Slave在21秒即完成了对Amazon网站10G key set的复制。
Ø Sharding
很容易将数据分布到多个Redis实例中,但这主要看该语言是否支持。目前支持Sharding功能的语言只有PHP、Ruby和Scala。
2、Redis数据类型
官方文档上,将Redis成为一个“数据结构服务器”(data structures server)是有一定道理的。Redis的所有功能就是以其固有的几种数据结构保存,并提供用户操作这几种结构的接口。可以对比在其他语言中那些固有数据类型及其操作。
Redis目前提供四种数据类型:string、list、set和zset(sorted set)。
2.1、String类型
String是最简单的类型,一个key对应一个value。Redis String是安全的,String类型的数据最大1G。String类型的值可以被视作integer,从而可以让“INCR”命令族操作,这种情况下,该integer的值限制在64位有符号数。
在list、set和zset中包含的独立的元素类型都是Redis String类型。
在Redis中,String类型由sds.c库定义,它被封装成Redis对象。和Java中的对象一样,Redis对象也是使用“引用”,因此当一个Redis String被多次使用时,Redis会尽量使用同一个String对象而不是多次分配。
从Redis 1.1版开始,String对象可以编码成数字,因此这样可以节省内存空间。
2.2、List类型
链表类型,主要功能是push、pop、获取一个范围的所有值等。其中的key可以理解为链表的名字。在Redis中,list就是Redis String的列表,按照插入顺序排序。比如使用LPUSH命令在list头插入一个元素,使用RPUSH命令在list的尾插入一个元素。当这两个命令之一作用于一个空的key时,一个新的list就创建出来了。比如:
最终在mylist中存储的元素为:”b”,”a”,”c”。
List的最大长度是2^32-1个元素。
3.3、Set类型
集合,和数学中的集合概念相似。操作中的key理解为集合的名字。在Redis中,set就是Redis String的无序集合,不允许有重复元素。对set操作的command一般都有返回值标识所操作的元素是否已经存在。比如SADD命令是往set中插入一个元素,如果set中已存在该元素,则命令返回0,否则返回1。
Set的最大元素数是2^32-1。
Redis中对set的操作还有交集、并集、差集等。
3.4、ZSet类型
Zset是set的一个升级版本,在set的基础上增加了一个顺序属性,这一属性在添加修改元素时可以指定,每次指定后zset会自动安装指定值重新调整顺序。可以理解为一张表,一列存value,一列存顺序。操作中的key理解为zset的名字。
比如ZADD命令是向zset中添加一个新元素,对该元素要指定一个score。如果对已经在zset中存在的元素施加ZADD命令同时指定了不同的score,则该元素的score将更新同时该元素将被移动到合适的位置以使集合保持有序。
使用ZRANGE命令可以得到zset的一部分元素,当然也可以使用命令ZRANGEBYSCORE,根据score得到或删除一部分元素。
Zset的最大元素数是2^32-1。
对于已经有序的zset,仍然可以使用SORT命令,通过指定ASC|DESC参数对其进行排序。
3.5、Hash类型
Redis Hash类型对数据域和值提供了映射,这一结构很方便表示对象。此外,在Hash中可以只保存有限的几个“域”,而不是将所有的“域”作为key,这可以节省内存。这一特性的体现可以参考下文的“虚拟内存”部分。
4、所有数据在内在中,但保存在硬盘上(All data in memory, but saved on disk)
Redis在内存中加载并维护整个数据集,但这些数据是持久化的,因为它们在同一时间被保持在磁盘上,所以当Redis服务重启时,这些数据能够重新被加载到内存中。
Redis支持两种数据持久化的方法。一种称为snapsshotting,在这种模式下,Redis异步地将数据dump到磁盘上。Redis还可以通过配置,根据更新操作次数或间隔时间,将数据dump到磁盘。比如你可以设定发生1000个更新操作时,或距上次转储最多60s就要将数据dump到磁盘。
因为数据是异步dump的,所以当系统崩溃时,就会出现错误。因为,Redis提供了另外一种模式,更安全的持久化模式,称为Append Only File,当出现修改数据命令的地方,这些命令就要写到“append only file”—ASAP。当服务重启时,这些命令会重新执行(replay)从而在内存中重新构建数据。
Redis的存储可以分为:内存存储、磁盘存储和log文件三部分,配置文件(redis.conf)中有三个参数对其进行配置。
save <seconds> <changes>:save配置,指出在多长时间,有多少次更新操作,就将数据同步到数据文件。在默认的配置文件中设置就设置了三个条件。
appendonly yes/no:appendonly配置,指出是否在每次更新操作后进行日志记录,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身同步数据文件是按上面的save条件来同步的,所以有的数据会在一段时间内只存在于内存中。
appendfsync no/always/everysec:appendfsync配置,no表示等操作系统进行数据缓存同步到磁盘,always表示每次更新操作后手动调用fsync()将数据写到磁盘,everysec表示每秒同步一次。
5、Redis的Master-Slave模式
Redis中配置Master-Slave模式很简单,二者会自动同步。配置方法是在从机的配置文件中指定slaveof参数为主机的ip和port即可,比如:slaveof 192.168.2.201 6379。从原理上来说,是从机请求主机的方式,按照tokyotyrant的做法,是可以实现主-主,主-从等灵活形式的,而redis只能支持主-从,不能支持主-主。Redis中的复制具有以下特点:
Ø 一个master可以有多个slave。
Ø 一个slave可以接收其他slave的链接,即不仅仅能连接一个master所属的slaves,而且能连接到slave的slave,从而形成了“图”结构。
Ø 在复制进行时,master是“非阻塞”的。即一个或多个slave对master进行第一次同步时,master仍然可以提供查询服务,而对于slave,当复制进行时则是“阻塞”的,期间slave不能响应查询。
Ø 复制可以用于提高数据的扩展性(比如多个slave用于只读查询),或者仅用于数据备份。
Ø 使用复制可以避免在master存储数据,通过修改redis.conf文件(将“save”的al注释),这样数据存储只在slave端进行。
slave连接master并发出SYNC命令开始复制或当连接关闭时与master同步数据。master在“后台”进行存储操作,同时会监听所有对数据的更新操作。当存储操作完成后,master开始向slave传送数据并将数据保存到磁盘,加载到内存。这一过程中,master将会向slave发送所有对数据有更新操作的命令。通过telnet可以实验这一过程。通过连接到Redis端口并且发出SYNC命令,在telnet的session中,可以看到数据包的传送,以及发送给master的命令都将重新发送给slave。
当master-slave连接断掉时,slave能自动重新建立连接。当一个master并发地收到多个slave数据同步请求时,master也能自动处理。
6、Redis虚拟内存管理
在Redis2.0开始(目前最新版本)第一次提出了Virtual Memory(VM)的特性。Redis是内存数据库,因此通常情况下Redis会将所有的key和value都放在内存中,但有时这并不是最好的选择,为了查询速度,可以将所有的key放在内存中,而values可以放在磁盘上,当用到时再交换到内存。
比如你的数据有100000个key都放在了内存中,而只有其中10%的key被经常访问,那么可进行VM配置的Redis会尝试将不经常访问的key关联的value放到磁盘上,当这些value被请求时才会交换到内存中。
什么时候使用VM配置是需要考虑的问题。因为Redis是以磁盘为后备的内存数据库,在大多数情况下,只有RAM足够大时才使用Redis。但实际情况是,总会出现内存不够的情况:
Ÿ 有“倾向”的数据访问。只有很小比例的key被经常访问(比如一个网站的在线用户),但同时在内存中却有所有的数据。
Ÿ 不考虑访问情况以及大的value,内存不能加载所有数据。这种情况下,Redis可以视作on-disk DB,即所有的key在内存中,而访问value时要访问慢速的磁盘。
需要注意的一点是,Redis不能交换key。即如果是因为数据的key太大,value太小而造成内存不够,VM是不能解决这种情况的。当出现这种情况时,有时可以使用Hash结构,将“many keys with small values”的问题转换成“less keys but with very values”的问题(对key进行hash,从而对数据进行“分组”)。
启用VM功能,只需要在redis.conf文件中使vm-enabled的值为yes。
7、Redis实例分析
仍然以用户和图片的例子进行说明。假设将图片存储在文件系统中,即类Image中只保存图片的uri。类Image和类User的代码参见MongoDB部分的例子。下面给出测试类的关键代码:
在实现中,将类User的对象实例存放在一个set中,所以利用了SADD命令,在Java中即调用JRedis对象的sadd方法。smembers方法将返回指定key(这里是userSet)的集合中的所有value,这样就可以对每一个元素进行操作。
8、Redis命令总结
Redis提供了丰富的命令(command)对数据库和各种数据类型进行操作,这些command可以在Linux终端使用。在编程时,比如使用Redis 的Java语言包,这些命令都有对应的方法,比如上面例子中使用的sadd方法,就是对集合操作中的SADD命令。下面将Redis提供的命令做一总结。
8.1、连接操作相关的命令
Ÿ quit:关闭连接(connection)
Ÿ auth:简单密码认证
8.2、对value操作的命令
Ÿ exists(key):确认一个key是否存在
Ÿ del(key):删除一个key
Ÿ type(key):返回值的类型
Ÿ keys(pattern):返回满足给定pattern的所有key
Ÿ randomkey:随机返回key空间的一个key
Ÿ rename(oldname, newname):将key由oldname重命名为newname,若newname存在则删除newname表示的key
Ÿ dbsize:返回当前数据库中key的数目
Ÿ expire:设定一个key的活动时间(s)
Ÿ ttl:获得一个key的活动时间
Ÿ select(index):按索引查询
Ÿ move(key, dbindex):将当前数据库中的key转移到有dbindex索引的数据库
Ÿ flushdb:删除当前选择数据库中的所有key
Ÿ flushall:删除所有数据库中的所有key
8.3、对String操作的命令
Ÿ set(key, value):给数据库中名称为key的string赋予值value
Ÿ get(key):返回数据库中名称为key的string的value
Ÿ getset(key, value):给名称为key的string赋予上一次的value
Ÿ mget(key1, key2,…, key N):返回库中多个string(它们的名称为key1,key2…)的value
Ÿ setnx(key, value):如果不存在名称为key的string,则向库中添加string,名称为key,值为value
Ÿ setex(key, time, value):向库中添加string(名称为key,值为value)同时,设定过期时间time
Ÿ mset(key1, value1, key2, value2,…key N, value N):同时给多个string赋值,名称为key i的string赋值value i
Ÿ msetnx(key1, value1, key2, value2,…key N, value N):如果所有名称为key i的string都不存在,则向库中添加string,名称key i赋值为value i
Ÿ incr(key):名称为key的string增1操作
Ÿ incrby(key, integer):名称为key的string增加integer
Ÿ decr(key):名称为key的string减1操作
Ÿ decrby(key, integer):名称为key的string减少integer
Ÿ append(key, value):名称为key的string的值附加value
Ÿ substr(key, start, end):返回名称为key的string的value的子串
8.4、对List操作的命令
Ÿ rpush(key, value):在名称为key的list尾添加一个值为value的元素
Ÿ lpush(key, value):在名称为key的list头添加一个值为value的 元素
Ÿ llen(key):返回名称为key的list的长度
Ÿ lrange(key, start, end):返回名称为key的list中start至end之间的元素(下标从0开始,下同)
Ÿ ltrim(key, start, end):截取名称为key的list,保留start至end之间的元素
Ÿ lindex(key, index):返回名称为key的list中index位置的元素
Ÿ lset(key, index, value):给名称为key的list中index位置的元素赋值为value
Ÿ lrem(key, count, value):删除count个名称为key的list中值为value的元素。count为0,删除所有值为value的元素,count>0从头至尾删除count个值为value的元素,count<0从尾到头删除|count|个值为value的元素。
Ÿ lpop(key):返回并删除名称为key的list中的首元素
Ÿ rpop(key):返回并删除名称为key的list中的尾元素
Ÿ blpop(key1, key2,… key N, timeout):lpop命令的block版本。即当timeout为0时,若遇到名称为key i的list不存在或该list为空,则命令结束。如果timeout>0,则遇到上述情况时,等待timeout秒,如果问题没有解决,则对key i+1开始的list执行pop操作。
Ÿ brpop(key1, key2,… key N, timeout):rpop的block版本。参考上一命令。
Ÿ rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部
8.5、对Set操作的命令
Ÿ sadd(key, member):向名称为key的set中添加元素member
Ÿ srem(key, member) :删除名称为key的set中的元素member
Ÿ spop(key) :随机返回并删除名称为key的set中一个元素
Ÿ smove(srckey, dstkey, member) :将member元素从名称为srckey的集合移到名称为dstkey的集合
Ÿ scard(key) :返回名称为key的set的基数
Ÿ sismember(key, member) :测试member是否是名称为key的set的元素
Ÿ sinter(key1, key2,…key N) :求交集
Ÿ sinterstore(dstkey, key1, key2,…key N) :求交集并将交集保存到dstkey的集合
Ÿ sunion(key1, key2,…key N) :求并集
Ÿ sunionstore(dstkey, key1, key2,…key N) :求并集并将并集保存到dstkey的集合
Ÿ sdiff(key1, key2,…key N) :求差集
Ÿ sdiffstore(dstkey, key1, key2,…key N) :求差集并将差集保存到dstkey的集合
Ÿ smembers(key) :返回名称为key的set的所有元素
Ÿ srandmember(key) :随机返回名称为key的set的一个元素
8.6、对zset(sorted set)操作的命令
Ÿ zadd(key, score, member):向名称为key的zset中添加元素member,score用于排序。如果该元素已经存在,则根据score更新该元素的顺序。
Ÿ zrem(key, member) :删除名称为key的zset中的元素member
Ÿ zincrby(key, increment, member) :如果在名称为key的zset中已经存在元素member,则该元素的score增加increment;否则向集合中添加该元素,其score的值为increment
Ÿ zrank(key, member) :返回名称为key的zset(元素已按score从小到大排序)中member元素的rank(即index,从0开始),若没有member元素,返回“nil”
Ÿ zrevrank(key, member) :返回名称为key的zset(元素已按score从大到小排序)中member元素的rank(即index,从0开始),若没有member元素,返回“nil”
Ÿ zrange(key, start, end):返回名称为key的zset(元素已按score从小到大排序)中的index从start到end的所有元素
Ÿ zrevrange(key, start, end):返回名称为key的zset(元素已按score从大到小排序)中的index从start到end的所有元素
Ÿ zrangebyscore(key, min, max):返回名称为key的zset中score >= min且score <= max的所有元素
Ÿ zcard(key):返回名称为key的zset的基数
Ÿ zscore(key, element):返回名称为key的zset中元素element的score
Ÿ zremrangebyrank(key, min, max):删除名称为key的zset中rank >= min且rank <= max的所有元素
Ÿ zremrangebyscore(key, min, max) :删除名称为key的zset中score >= min且score <= max的所有元素
Ÿ zunionstore / zinterstore(dstkeyN, key1,…,keyN, WEIGHTS w1,…wN, AGGREGATE SUM|MIN|MAX):对N个zset求并集和交集,并将最后的集合保存在dstkeyN中。对于集合中每一个元素的score,在进行AGGREGATE运算前,都要乘以对于的WEIGHT参数。如果没有提供WEIGHT,默认为1。默认的AGGREGATE是SUM,即结果集合中元素的score是所有集合对应元素进行SUM运算的值,而MIN和MAX是指,结果集合中元素的score是所有集合对应元素中最小值和最大值。
8.7、对Hash操作的命令
Ÿ hset(key, field, value):向名称为key的hash中添加元素field<—>value
Ÿ hget(key, field):返回名称为key的hash中field对应的value
Ÿ hmget(key, field1, …,field N):返回名称为key的hash中field i对应的value
Ÿ hmset(key, field1, value1,…,field N, value N):向名称为key的hash中添加元素field i<—>value i
Ÿ hincrby(key, field, integer):将名称为key的hash中field的value增加integer
Ÿ hexists(key, field):名称为key的hash中是否存在键为field的域
Ÿ hdel(key, field):删除名称为key的hash中键为field的域
Ÿ hlen(key):返回名称为key的hash中元素个数
Ÿ hkeys(key):返回名称为key的hash中所有键
Ÿ hvals(key):返回名称为key的hash中所有键对应的value
Ÿ hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value
8.8、持久化
Ÿ save:将数据同步保存到磁盘
Ÿ bgsave:将数据异步保存到磁盘
Ÿ lastsave:返回上次成功将数据保存到磁盘的Unix时戳
Ÿ shundown:将数据同步保存到磁盘,然后关闭服务
8.9、远程服务控制
Ÿ info:提供服务器的信息和统计
Ÿ monitor:实时转储收到的请求
Ÿ slaveof:改变复制策略设置
Ÿ config:在运行时配置Redis服务器
最后
以上就是笑点低草莓为你收集整理的Redis简介1、Redis简介2、Redis数据类型4、所有数据在内在中,但保存在硬盘上(All data in memory, but saved on disk)5、Redis的Master-Slave模式6、Redis虚拟内存管理7、Redis实例分析8、Redis命令总结的全部内容,希望文章能够帮你解决Redis简介1、Redis简介2、Redis数据类型4、所有数据在内在中,但保存在硬盘上(All data in memory, but saved on disk)5、Redis的Master-Slave模式6、Redis虚拟内存管理7、Redis实例分析8、Redis命令总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复