北京塞车网站建设,怎么做情侣网站,电商网站建设行业现状,淘宝网页版怎么和卖家聊天1、数据类型 String(字符串#xff0c;整数#xff0c;浮点数)#xff1a;做简单的键值对缓存
List(列表)#xff1a;储存一些列表类型的数据结构
Hash(哈希)#xff1a;包含键值对的无序散列表#xff0c;结构化的数据
Set(无序集合)#xff1a;交集#xff0c;并集…1、数据类型 String(字符串整数浮点数)做简单的键值对缓存
List(列表)储存一些列表类型的数据结构
Hash(哈希)包含键值对的无序散列表结构化的数据
Set(无序集合)交集并集差集的操作
Zset(有序集合)(Sorted sets)去重同时也可以排序 先通过一张图了解下Redis内部内存管理中是如何描述这些不同数据类型的 首先Redis内部使用一个redisObject对象来表示所有的key和valueredisObject最主要的信息如上图所示type代表一个value对象具体是何种数据类型encoding是不同数据类型在redis内部的存储方式比如typestring代表value存储的是一个普通字符串那么对应的encoding可以是raw或者是int如果是int则代表实际redis内部是按数值型类存储和表示这个字符串的当然前提是这个字符串本身可以用数值表示比如:123 456这样的字符串。 这里需要特殊说明一下vm字段只有打开了Redis的虚拟内存功能此字段才会真正的分配内存该功能默认是关闭状态的。通过上图我们可以发现Redis使用redisObject来表示所有的key/value数据是比较浪费内存的当然这些内存管理成本的付出主要也是为了给Redis不同数据类型提供一个统一的管理接口实际作者也提供了多种方法帮助我们尽量节省内存使用我们随后会具体讨论。 一、string
string 是 redis 最基本的类型你可以理解成与 Memcached 一模一样的类型一个 key 对应一个 value。value其实不仅是String也可以是数字。string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。string 类型是 Redis 最基本的数据类型string 类型的值最大能存储 512MB。 常用命令get、set、incr、decr、mget等。 应用场景String是最常用的一种数据类型普通的key/ value 存储都可以归为此类即可以完全实现目前 Memcached 的功能并且效率更高。还可以享受Redis的定时持久化操作日志及 Replication等功能。除了提供与 Memcached 一样的get、set、incr、decr 等操作外Redis还提供了下面一些操作 获取字符串长度
往字符串append内容
设置和获取字符串的某一段内容
设置及获取字符串的某一位bit
批量设置一系列字符串的内容
使用场景常规key-value缓存应用。常规计数: 微博数, 粉丝数。 实现方式String在redis内部存储默认就是一个字符串被redisObject所引用当遇到incr,decr等操作时会转成数值型进行计算此时redisObject的encoding字段为int。 redis 127.0.0.1:6379 SET name runoob
OK redis 127.0.0.1:6379 GET name
runoob
在以上实例中我们使用了 Redis 的 SET 和 GET 命令。键为 name对应的值为 runoob。 **注意**一个键最大能存储512MB。 二、Hash
Hash 是一个键值(key value)对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表hash 特别适合用于存储对象。 常用命令hget,hset,hgetall 等。 应用场景我们简单举个实例来描述下Hash的应用场景比如我们要存储一个用户信息对象数据包含以下信息 用户ID为查找的key存储的value用户对象包含姓名年龄生日等信息如果用普通的key/value结构来存储主要有以下2种存储方式 image 第一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储这种方式的缺点是增加了序列化/反序列化的开销并且在需要修改其中一项信息时需要把整个对象取回并且修改操作需要对并发进行保护引入CAS等复杂问题。 image 第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿用用户ID对应属性的名称作为唯一标识来取得对应属性的值虽然省去了序列化开销和并发问题但是用户ID为重复存储如果存在大量这样的数据内存浪费还是非常可观的。 那么Redis提供的Hash很好的解决了这个问题Redis的Hash实际是内部存储的Value为一个HashMap并提供了直接存取这个Map成员的接口如下图 image 也就是说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。 redis HSET myhash field1 Hello field2 World
OK redis HGET myhash field1
Hello redis HGET myhash field2
World
实例中我们使用了 Redis HMSET, HGET 命令HMSET 设置了两个 fieldvalue 对, HGET 获取对应 field 对应的 value。每个 hash 可以存储 232 -1 键值对40多亿。 三、list
list 列表是简单的字符串列表按照插入顺序排序。你可以添加一个元素到列表的头部左边或者尾部右边。 常用命令lpush添加左边元素,rpush,lpop移除左边第一个元素,rpop,lrange获取列表片段LRANGE key start stop等。 应用场景Redis list的应用场景非常多也是Redis最重要的数据结构之一比如twitter的关注列表粉丝列表等都可以用Redis的list结构来实现。 List 就是链表相信略有数据结构知识的人都应该能理解其结构。使用List结构我们可以轻松地实现最新消息排行等功能。List的另一个应用就是消息队列 可以利用List的PUSH操作将任务存在List中然后工作线程再用POP操作将任务取出进行执行。Redis还提供了操作List中某一段的api你可以直接查询删除List中某一段的元素。 实现方式Redis list的实现为一个双向链表即可以支持反向查找和遍历更方便操作不过带来了部分额外的内存开销Redis内部的很多实现包括发送缓冲队列等也都是用的这个数据结构。 Redis的list是每个子元素都是String类型的双向链表可以通过push和pop操作从列表的头部或者尾部添加或者删除元素这样List即可以作为栈也可以作为队列。 获取越接近两端的元素速度越快但通过索引访问时会比较慢。 使用场景 消息队列系统使用list可以构建队列系统使用sorted set甚至可以构建有优先级的队列系统。比如将Redis用作日志收集器实际上还是一个队列多个端点将日志信息写入Redis然后一个worker统一将所有日志写到磁盘。 取最新N个数据的操作记录前N个最新登陆的用户Id列表超出的范围可以从数据库中获得。 复制代码
//把当前登录人添加到链表里
ret r.lpush(login:last_login_times, uid) //保持链表只有N位
ret redis.ltrim(login:last_login_times, 0, N-1) //获得前N个最新登陆的用户Id列表
last_login_list r.lrange(login:last_login_times, 0, N-1)
复制代码
比如微博 在Redis中我们的最新微博ID使用了常驻缓存这是一直更新的。但是我们做了限制不能超过5000个ID因此我们的获取ID函数会一直询问Redis。只有在start/count参数超出了这个范围的时候才需要去访问数据库。我们的系统不会像传统方式那样“刷新”缓存Redis实例中的信息永远是一致的。SQL数据库或是硬盘上的其他类型数据库只是在用户需要获取“很远”的数据时才会被触发而主页或第一个评论页是不会麻烦到硬盘上的数据库了。
复制代码
redis 127.0.0.1:6379 lpush runoob redis
(integer) 1 redis 127.0.0.1:6379 lpush runoob mongodb
(integer) 2 redis 127.0.0.1:6379 lpush runoob rabitmq
(integer) 3 redis 127.0.0.1:6379 lrange runoob 0 10
1) rabitmq
2) mongodb
3) redis redis 127.0.0.1:6379
复制代码
列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。 四、 set
set 是string类型的无序集合。集合是通过hashtable实现的概念和数学中个的集合基本类似可以交集并集差集等等set中的元素是没有顺序的。所以添加删除查找的复杂度都是O(1)。 *sadd 命令*添加一个 string 元素到 key 对应的 set 集合中成功返回1如果元素已经在集合中返回 0如果 key 对应的 set 不存在则返回错误。 常用命令sadd,spop,smembers,sunion 等。 应用场景Redis set对外提供的功能与list类似是一个列表的功能特殊之处在于set是可以自动排重的当你需要存储一个列表数据又不希望出现重复数据时set是一个很好的选择并且set提供了判断某个成员是否在一个set集合内的重要接口这个也是list所不能提供的。 Set 就是一个集合集合的概念就是一堆不重复值的组合。利用Redis提供的Set数据结构可以存储一些集合性的数据。 案例在微博中可以将一个用户所有的关注人存在一个集合中将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作可以非常方便的实现如共同关注、共同喜好、二度好友等功能对上面的所有集合操作你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。 实现方式 set 的内部实现是一个 value永远为null的HashMap实际就是通过计算hash的方式来快速排重的这也是set能提供判断一个成员是否在集合内的原因。 使用场景 ①交集并集差集(Set) 复制代码
//book表存储book名称
set book:1:name ”The Ruby Programming Language”
set book:2:name ”Ruby on rail”
set book:3:name ”Programming Erlang” //tag表使用集合来存储数据因为集合擅长求交集、并集
sadd tag:ruby 1 sadd tag:ruby 2 sadd tag:web 2 sadd tag:erlang 3
//即属于ruby又属于web的书
inter_list redis.sinter(tag.web, tag:ruby) //即属于ruby但不属于web的书
inter_list redis.sdiff(tag.ruby, tag:web) //属于ruby和属于web的书的合集
inter_list redis.sunion(tag.ruby, tag:web)
复制代码
②获取某段时间所有数据去重值 这个使用Redis的set数据结构最合适了只需要不断地将数据往set中扔就行了set意为集合所以会自动排重。 sadd key member
复制代码
redis 127.0.0.1:6379 sadd runoob redis
(integer) 1 redis 127.0.0.1:6379 sadd runoob mongodb
(integer) 1 redis 127.0.0.1:6379 sadd runoob rabitmq
(integer) 1 redis 127.0.0.1:6379 sadd runoob rabitmq
(integer) 0 redis 127.0.0.1:6379 smembers runoob
1) redis
2) rabitmq
3) mongodb
复制代码
**注意** 以上实例中 rabitmq 添加了两次但根据集合内元素的唯一性第二次插入的元素将被忽略。集合中最大的成员数为 232 - 1(4294967295, 每个集合可存储40多亿个成员)。 五 、zset
zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。 *zadd 命令*添加元素到集合元素在集合中存在则更新对应score。 常用命令zadd,zrange,zrem,zcard等 使用场景Redis sorted set的使用场景与set类似区别是set不是自动有序的而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序并且是插入有序的即自动排序。当你需要一个有序的并且不重复的集合列表那么可以选择sorted set数据结构比如twitter 的public timeline可以以发表时间作为score来存储这样获取时就是自动按时间排好序的。和Set相比Sorted Set关联了一个double类型权重参数score使得集合中的元素能够按score进行有序排列redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。比如一个存储全班同学成绩的Sorted Set其集合value可以是同学的学号而score就可以是其考试得分这样在数据插入集合的时候就已经进行了天然的排序。另外还可以用Sorted Set来做带权重的队列比如普通消息的score为1重要消息的score为2然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。