Java-Redis(知识点及实际项目运用中)(一)

Java-Redis(知识点及实际项目运用中)(一)

1、简介:

1.1、数据结构

作为 key-value 型数据库,Redis 提供了 键(Key)键值(Value)的映射关系。但是,除了常规的 数值或字符串,Redis 的键值(Value)还可以是一下形式之一:

strings(byte数组):byte数组,可以包含任何数据,图片、序列等;最大上限 1G字节。

Lists(列表):先入后出

Sets(集合):

Sorted sets(有序集合):

Hashes(哈希表):

键值的数据类型决定了该键值支持的操作。Redis 支持诸如列表、集合或有序集合的交集、并集、查集等 高级原子操作;同时如果键值的类型是普通数字,Redis则提供自增等原子操作。

1.2、持久化

通常,Redis将数据存储于内存中,或被配置为使用虚拟机内存。通过两种方式可以实现数据持久化: 使用截图方式,将内存中的数据不断写入磁盘;或使用类似于 MySQL 的日志方式,记录每次更新的日志 。前者性能比较高,但可能会引起一定程度的数据丢失;后者相反。

1.3、主从同步

Redis 支持将数据同步到多各从库上,这种特性对提高读写性能非常有益。

2、数据类型及操作

2.1、strings

set设置 key 值get获取 key 值setnxnx(not exist),设置 key 值, 如果key已存在返回 0getset设置 key 的值,返回 key 的旧值setex指定键值对应的有效期 setex haircolor 10 redgetrange获取 key 值的子字符串 getrange name 0 6setrange设置 key 值的子字符串 setrange key 4 bbbmset一次设置多个key值,成功返回OK 失败 0mget一次获取多个 key 的值,如果key不存在,则返回 nilmsetnx同上,失败返回0,没有任何值被设置,不会覆盖已存在的keyincr对 key的值做 ++ 操作,并返回新值 incr 一个不是 int 的 value 会返回错误incrby加指定值,返回新值;key不存在会设置新值,并默认原值为 0decr对key的值做 — — 操作,decr 一个不存在 key,则设置 key 为-1decrby同 decr,减指定值append给指定 key 的字符串值追加 value,返回新字符串值的长度。strlen取指定 key 的 value 值的长度。

2.2、lists

list 链表结构,主要操作pushpop、获取一个范围所有值等等,操作中 key 理解为链表的名字。

Redis 的 list 类型其实就是一个每个子元素都是 string 类型的双向链表。链表的最大长度是(2的 32 次方)。我们可以通过 push,pop 操作从链表的头部或者尾部添加删除元素。这使得 list既可以用作栈,也可以用作队列。

有意思的是 list 的 pop 操作还有阻塞版本的,当我们[lr]pop 一个 list 对象时,如果 list 是空,或者不存在,会立即返回 nil。但是阻塞版本的 b[lr]pop 可以则可以阻塞,当然可以加超时时间,超时后也会返回 nil。为什么要阻塞版本的 pop 呢,主要是为了避免轮询。举个简单的例子如果我们用 list 来实现一个工作队列。执行任务的 thread 可以调用阻塞版本的 pop 去获取任务这样就可以避免轮询去检查是否有任务存在。当任务来时候工作线程可以立即返回,也可以避免轮询带来的延迟。操作:

lpushrpushlinsertlsetlremltrimlpoprpoprpoplpushlindexllen

2.3、sets

set 是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作,操作中 key 理解为集合的名字。

set 的是通过 hash table 实现的,所以添加、删除和查找的复杂度都是 O(1)。hash table 会随着添加或者删除自动的调整大小。需要注意的是调整 hash table 大小时候需要同步(获取写锁)会阻塞其他读写操作,可能不久后就会改用跳表(skip list)来实现,跳表已经在 sorted set 中使用了。关于 set 集合类型除了基本的添加删除操作,其他有用的操作还包含集合的取并集(union),交集(intersection),差集(difference)。通过这些操作可以很容易的实现 sns中的好友推荐和 blog 的 tag 功能。

sadd向名称为key的set中添加元素,smembers查看元素srem删除 set中指定元素 srem set "one"spop随机删除并返回这个元素sdiffstoresdiffstore set4 set2 set3返回给定key与第一个key的差集,并将结果存于 set4sdiffsdiff set1 set2,返回set1 的差集sinter返回两个set 的交集部分sinterstoresinterstore set5 set2 set3 set2 set3的并集存于 set5sunion返回所有给定 key 的并集sunionstore返回所有给定 key 的并集,并将结果存为另一个 keysmovesmove set2 set3 three ;从第一个 key 对应的 set 中移除 member 并添加到第二个对应 set 中scard返回名称为 key 的 set 的元素个数sismenbersismember set value ;如果 value在 set中返回 1,不在 0srandmember随机返回 set 的一个元素,但是不删除元素

2.4、sorted set

sorted set 是 set的一个升级版,它在 set的基础上增加一个顺序属性,这一属性在添加 修改元素的时候可以指定,每次指定后,zset 会自动重新按新的值调整顺序。可以理解为有两列的 mysql 表,一列存 value,一列存顺序。操作中 key 理解为 zset 的名字。

和 set 一样 sorted set 也是 string 类型元素的集合,不同的是每个元素都会关联一个 double类型的 score。sorted set 的实现是 skip list 和 hash table 的混合体。

当元素被添加到集合中时,一个元素到 score 的映射被添加到 hash table 中,所以给定一个元素获取 score 的开销是 O(1),另一个 score 到元素的映射被添加到 skip list,并按照 score 排序,所以就可以有序的获取集合中的元素。添加,删除操作开销都是 O(log(N))和 skip list 的开销一致,redis 的 skip list 实现用的是双向链表,这样就可以逆序从尾部取元素。sorted set 最经常的使用方式应该是作为索引来使用.我们可以把要排序的字段作为 score 存储,对象的 id当元素存储。

zaddzadd myzset score "元素" ; 向 key 的 zset 中添加元素 score 用于排序,如果元素已存在score 更新元素顺序,以最后一次设置为准zrem删除名称为 key 的 zset 中的元素zincrbyzset 中已经存在元素 ,则该元素的 score 相加;否则向集合中添加该元素,其 score 的值为 添加时的scorezrank返回元素在key中的排名(元素下标,小到大)zrangezrange myzset3 0 -1 withscoreszrevrank返回元素在zset的排名(大到小)zrevrange返回zset(按 score 从大到小排序)中的 index 从 start 到 end 的所有元素zrangebyscore返回集合中 score 在给定区间的元素zcount返回集合中 score 在给定区间的数量zcard返回集合中元素个数zscore返回给定元素对应的 scorezremrangebyrank删除集合中排名在给定区间的元素

zremrangebyscore删除集合中 score 在给定区间的元素

2.5、hashes

hash适合存储对象,hash 比将对象属性单个存储为string,更便于存取和节省内存;

省内存的原因是新建一个hash 对象时开始是用 zipmap(又称 small hash) 来存储。

zipmap 不是hash table 但是相比 hash可以节省不少元素开销。如果元素字段过多 redis会自动将zipmap 替换成正常的 hash实现,这个限制大小可以手动配置:

hash-max-zipmap-entries 64 #配置字段最多 64 个

hash-max-zipmap-entries 64 #配置字段最多 64 个

hset设置 hash field 值,如果 key 不存在,则先创建。hsetnx设置 hash field 值,如果 key 不存在,则先创建。如果 field 已经存在,返回 0,nx 是not exist 的意思。hmset同时设置 hash 的多个 field。hget获取指定的 hash field。空值 nilhmget获取全部指定的 hash filed。hincrby指定的 hash filed 加上给定值。hexists

测试指定 field 是否存在。hlen返回指定 hash 的 field 数量。hdel返回指定 hash 的 field 数量。hkeys返回 hash 的所有 fieldhvals返回 hash 的所有 value。hgetall获取某个 hash 中全部的 filed 及 value。

3、Redis 常用命令

Redis 提供了丰富的命令(command)对数据库和各种数据类型进行操作,这些 command可以在 Linux 终端使用。在编程时,比如各类语言包,这些命令都有对应的方法。

3.1、键值相关命令

keys:keys *

用表达式*,代表取出所有的 key;

exists: exists key

确认这个 key是否存在(不存在 0 | 存在1);

del:del key

删除一个 key;

expire:expire key 10

设置这个 key 的过期时间(单位:秒) ;ttl 获取这个key ,-1 代表过期;

move:move key 库名

将当前数据库中的 key 转移到其它数据库中;

persist:persist key

移除给定 key的活期时间;

randomkey:randomkey

随机返回一个 key

rname:rname oldname newname

重命名

type:type key

返回 key的类型

3.2、服务器相关命令

ping:ping 连接是否正常

echo: echo string

在命令行打印 string

select:select 数据库名

选择数据库,Redis 数据库编号从 0~15,可以任意选择一个数据库进行操作

quit:quit 退出连接

dbsize:dbsize 返回当前数据库 key的数目

info:info 获取服务器的信息和统计

此结果用于说明服务器的基础信息,包括版本、启动时间等。

monitor:实时转储收到的请求。

config get:config get dir 获取服务配置信息

获取 dir 这个参数配置的值;获取所有配置信息 config get *

flushdb:flushdb 删除当前数据库的所有 key

flushall:flushall 删除所有数据库中所有 key

4、适用场景:

4.1、获取最新 N 个数据的操作:

比如典型的取网站最新文章,通过下面方式,我们可以将最新的 5000 条评论的 ID 放在 Redis 的 List 集合,并将超出集合部分从数据库获取。

使用 LPUSH latest.comments命令,向集合中插入数据,插入完成后再用 LTRIM latest.comments 0 5000命令使其永远只保存最近 5000 个 ID 然后我们在客户端获取某一项评论时可以用下面

逻辑。

FUNCTION get_latest_comments(start,num_items):
 id_list = redis.lrange("latest.comments",start,start+num_items-1)
 IF id_list.length < num_items
 id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")
 END
 RETURN id_list
END

如果还有不同的筛选维度,比如某个分类的最新 N 条,可以再建一个按此分类的 List,只存 ID 的话,Redis非常高效。

4.2、排行榜应用,取 TOP N操作:

4.3、需要精准设定过期时间的应用:

4.4、计数器应用:

4.5、Uniq 操作,获取某段时间所有数据排重值:

4.6、实时系统,反垃圾系统

4.7、Pub/Sub 构建实时消息系统

4.8、构建队列系统

4.9、缓存


分享到:


相關文章: