目录
1、Redis 介绍
课程内容
1、了解Redis
2、Redis支持的数据类型:5种基础类型、3种特殊类型,基础命令介绍
3、数据持久化:两种方法
4、Redis的事务
5、Redis.conf详解
6、Jedis:通过Java代码操作Redis
7、Redis问题及解决方案:缓存穿透、缓存雪崩等
8、Redis的集群方案:主从复制、哨兵模式等
2、了解Redis
2.1、Redis介绍
Redis官网:redis中文官方网站
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
它支持多种类型的数据结构,如 字符串(strings), 散列(hashes),列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。
Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
Redis是基于C++实现,NoSQL数据库(非关系型数据库),以Key-Value键值对的形式来存储数据。
MySQL:关系型数据库
2.2、Redis的优点:
2.2.1、基于内存存储数据,内存读写速度快
2.2.2、Redis是单线程。避免线程切换开销以及线程竞争的问题
2.2.3、支持丰富的数据类型
2.2.4、支持持久化,Redis总共支持RDB和AOF两种持久化方案,持久化有效避免数据丢失的问题
2.2.5、支持事务。Redis中的操作是具有原子性的
2.2.6、支持主从复制,主节点将数据同步给从节点,可以进行读写分离。
2.3、Redis的基本操作
Redis中默认有16个数据库,默认是使用第0个数据库,可以通过select进行切换
2.3.1、select
切换数据库 格式:select index
2.3.2、dbsize
查看当前数据库中数据个数 格式:dbsize
2.3.3、keys
查看所有key 格式:keys *
2.3.4、flushdb flushall
清空当前数据库(flushdb)和清空所有数据库(flushAll)
2.4、Redis的单线程的
Redis是基于内存操作,CPU不是Redis的性能瓶颈,Redis的性能问题自安于机器内存和网络带宽,既然可以使用单线程来实现,就优先选择单线程
2.4.1、单线程好处:
避免过多的上下文切换的开销。
避免同步机制的开销,如果是多线程模型,需要考虑数据同步的问题,必然引入同步机制,比如锁机制,增加程序复杂度
实现比较简单,方便维护。
快:体现在单线程、采用比较高效的网络IO模型(linux系统下select/poll/epoll)
2.5、Redis的基本数据类型
Redis命令格式:command key value
2.5.1、String:字符串
String类型是Redis中的基本类型,一个key对应一个value
String类型的值可以是字符串,数字或者是二进制的数据,最大不超过512M
①set
添加数据 格式:set key value
②get
获取值,通过key获取value 格式:get key
③exists
判断key是否存在 格式:exists key
④append
追加字符串,如果key存在,追加;key不存在,相当于set 格式:append key append_value
⑤strlen
获取字符串的长度 格式:strlen key
⑥incr decr
对value进行自增1 格式:incr key
对value进行自减1 格式:decr key
能够进行自增自减的字符串必须是数据字符串,否则抛出错误
如果对应key不存在,那么value的值会先被初始化为0,然后在执行incr操作
⑦incrby decrby
设置加的步长 格式:incrby key num
设置减的步长 格式:decrby key num
⑧getrange
获取给定范围的字符串的值
格式:getrange key start stop
⑨setrange
从指定位置开始替换字符串的值
格式:setrange key offset value
返回值表示value的长度
10、setex ttl
设置过期时间 格式:setex key seconds value
查看剩余时间 格式:ttl key
注意:时间单位是秒
ttl执行结束是-2
11、setnx
(set if not exists)如果key不存在则设置,否则失败不设置
格式:setnx key value
基于setnx实现分布式锁
12、mset mget
批量的插入数据 格式:mset k1 v1 k2 v2 ...kn vn
批量的获取数据 格式:mget k1 k2 ...kn
13、getset
先获取值,然后在设置值 格式:getset key value
2.5.2、Hash:哈希
Redis中的哈数是一个String类型的filed和value的映射表,本身是一种键值对的结构
哈希类型很适合存储对象
哈希的命令都是以h开头,hset、hget...
①hset、hget
设置数据 格式:hset key filed1 value1 ...fieldn valuen
获取数据 格式:hget key field
插入操作返回结果表示插入成功数据格式,filed属性是不能重复的
②hmset hmget
插入数据 格式:hmset key filed1 value1 ...fieldn valuen
批量获取数据 格式:hmget key field1...fieldn
③hgetall
获取key中所有的value值
④hdel
删除指定field的hash键值对 格式:hdel key filed
⑤hlen
获取哈希中键值对的个数 格式:hlen key filed
⑥hexists
判断哈希中字段是否存在 格式:hexists key filed
⑦hkeys hvals
获取哈希中key的所有filed 格式:hkeys key
获取哈希中key的所有value 格式:hvals key
⑧hincrby
给定哈希中字段的值加上一定步长 格式:hincrby key filed num
⑨hsexnx
如果 不存在,则添加成功,如果存在,则失败 格式:hsetnx key filed value
场景:主要是存储对象。
2.5.3、List:列表
列表是简单的字符串列表,按照插入顺序排序,数据是可以重复的。可以在头部和尾部进行插入和删除,
类似于Java中的LinkedList集合
可以使用该类型实现栈、队列等数据结构
①lpush rpush
从list的左边插入值 格式:lpush key value
从list的右边插入值 格式:rpush key value
Xpush操作返回的是list中数据的个数
②lrange
从list中获取指定范围的数据 格式:lrange key start stop
lpop rpop
从列表的左侧删除数据 格式:lpop key
从列表的右侧删除数据 格式:rpop key
③lindex
获取指定下标的值 格式:lindex key index
④llen
获取list中元素的个数 格式:llen key
⑤lrem
删除list中元素 格式:lrem key count value
⑥ltrim
截取列表中的值 格式:ltrim key start stop
⑦rpoplpush
移除列表中的最后一个元素,将他添加到另一个列表中
格式:rpoplpush key1 key2
⑧lset
根据下标替换列表中的值 格式:lset key index value
⑨linsert
在列表中插入值 格式:linsert key before|after value new_value
在指定元素前或者后插入数据,如果指定数据重复,只找到第一个出现的元素在其前后插入即可
使用列表完成数据结构:
实现栈:lpush+lpop
实现队列:lpush+rpop
有限集合:lpush+ltrim
2.5.4、Set:集合
redis中的set是String类型的无序集合,数据是无序的,并且属性元素是唯一的,意味着不能出现重复元素
命令都是以s开头的
sadd
给set中添加元素 格式:sadd key value1 value2...valuen
smembers
获取set中所有的值 格式:smembers key
sismember
判断某个元素是否在set中 格式:sismember key value
scard
获取set中元素的个数 格式:scard key
srem
删除set中的元素 格式:srem key value1 value2...
srandmember
从set中随机获取值 格式:srandmember key count
spop
随机删除指定元素格式 格式:spop key count
smove
将指定元素从一个set中移动到另一个set中 格式:smove set1 set2 value
可以实现推荐好友或者共同关注的人
2.5.5、SortSet:有序集合
sortset和set类似,存在特征:集合中数据元素不能重复。
有序集合可以实现元素排序,给定每个元素设置一个分数,作为排序依据
注意:有序集合中元素是不能重复的,但是分数可以重复
有序集合一般是以z开头的
zadd
添加元素 格式:zadd key socre value
zrange
获取zset中一个范围的值 格式:zrange key start stop
zrangebyscore
按照zset从小到大排序 格式:zrangebyscore key min max
zrem
删除zset中的元素 格式:zrem key value
zcard
查看zset中元素个数 格式:zcard key
zcount
更具score的值统计在给定区间的元素个数 格式:zcount key min max
排行榜、按照时间序列的新闻
2.6、应用场景
1、缓存
一般使用String类型。
缓存热点数据(weibo 热搜)、对象缓存、页面缓存,降低数据库压力
2、数据共享
redis相对于引用是独立服务,可以在多个应用之间共享
例如:共享session
3、分布式锁
String类型sexnx,只有在不存在是才能添加成功
public static boolean getLock(String key) { Long flag = jedis.setnx(key,"1"); if (flag == 1) return true; else return false; }
4、全局ID
给定一个全局发号器 ,一次给定一段号,每个服务器使用完在来申请
incrby 通过步长设置来获取,利用Redis操作的原子性。
Twitter:snowflow:雪花算法
美团:Leaf
5、计数器
incr方法
例如:文章阅读量、微博的点赞量
6、限流
一般通过访问的IP加其他信息作为key,访问一次加1,超过设定的阈值直接返回
7、Top问题
微博热搜按照访问量 zset处理
8、消息队列
list提供了两端操作的方法,rpush/lpush.rpop/rpush等操作
通过操作可以实现队列,栈等结构
9、用户关注、推荐模型
sdiff set1 set2 获取差集 推荐(好友推荐、粉丝推荐、关注话题推荐)
sinter set1 set2 获取交集(共同好友、共同话题)
sunion set1 set2 获取并集(所有好友,所有话题)
10、排行榜
新闻排行榜、微博热搜