0%

Redis —— 初识Redis

Redis系列:

Redis官网
Redis中文官网

什么是Redis

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如字符串(string)、散列(hash)、列表(list)、集合(set)、有序集合(sorted set)与范围查询、bitmaps、 hyperloglogs 和地理空间(geospatial) 索引半径查询。Redis内置了复制(replication),Lua脚本(Lua scripting),LRU驱动事件(LRU eviction),事务(transactions)和不同级别的磁盘持久化(persistence), 并通过 Redis Sentinel 和自动 Redis Cluster 提供高可用性(high availability)。

Redis 支持很多特性,例如将内存中的数据持久化到硬盘中,使用复制来扩展读性能,使用分片来扩展写性能。

Redis 优势

  • 性能极高:Redis能读的速度是110000次/s,写的速度是81000次/s
  • 丰富的数据类型:Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作
  • 原子:Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,但不保证原子性
  • 丰富的特性:Redis还支持 publish/subscribe、通知、key 过期等特性

Redis 能做什么?

开发人员都只带Redis可以用来做缓存,除了缓存以外还可以做什么?
下面来自老钱的 Redis 深度历险:核心原理与应用实践

  • 记录帖子的点赞数、评论数和点击数 (hash)。
  • 记录用户的帖子 ID 列表 (排序),便于快速显示用户的帖子列表 (zset)。
  • 记录帖子的标题、摘要、作者和封面信息,用于列表页展示 (hash)。
  • 记录帖子的点赞用户 ID 列表,评论 ID 列表,用于显示和去重计数 (zset)。
  • 缓存近期热帖内容 (帖子内容空间占用比较大),减少数据库压力 (hash)。
  • 记录帖子的相关文章 ID,根据内容推荐相关帖子 (list)。
  • 如果帖子 ID 是整数自增的,可以使用 Redis 来分配帖子 ID(计数器)。
  • 收藏集和帖子之间的关系 (zset)。
  • 记录热榜帖子 ID 列表,总热榜和分类热榜 (zset)。
  • 缓存用户行为历史,进行恶意行为过滤 (zset,hash)。

为什么 Redis是单线程模型,还会达到每秒万级别的处理能力?

1、内存访问,Redis 将所有数据放到内存中,内存的响应时长大约为100纳秒,这是 Redis 达到每秒万级别访问的重要基础;
2、非阻塞 I/O,Redis 使用 epoll 作为 I/O 多路复用技术的实现,再加上 Redis 自身的事件处理模型将 epoll 中的连接、读写、关闭都转化为事件,不在网络 I/O 上浪费事件;

  • 阻塞 IO: 资源不可用时,IO 请求一直阻塞,直到反馈结果(有数据或超时)
  • 非阻塞 IO:资源不可用时,IO 请求离开返回,返回数据标识资源不可用

3、单线程避免了线程切换和竞争产生的消耗。

安装Redis

详细的教程这里就不写了,给篇 参考文献

Redis基本类型

只讲一些常用的,详细的可以去官网查看。

String

基本命令

1
2
3
4
SET key value  设置指定 key 的值
GET key 获取指定 key 的值
del key 删除指定key值
GETRANGE key start end 返回 key 中字符串值的子字符

对于字符串类型的保存,上面的知识简单的,如果你在终端中保存,它提示的命令其实不止是上面看到的。set key value [EX seconds] [PX milliseconds] [NX|XX],这才是它所提供全部的命令。不过从这个命令中可以看出,在后来版本的Redis中,基本上 set 命令取代了 setnx

  • EX/PX: EX 指的是秒数;PX 指的是毫秒
  • NX/XX:NX 表示当key不存在时,创建保存;XX 表示当key存在时,保存value

Hash

1
2
3
4
5
HDEL key field1 [field2]  删除一个或多个哈希表字段
HEXISTS key field 查看哈希表 key 中,指定的字段是否存在
HGET key field 获取存储在哈希表中指定字段的值
HGETALL key 获取在哈希表中指定 key 的所有字段和值
HMSET key field1 value1 [field2 value2 ] 同时将多个 field-value (域-值)对设置到哈希表 key 中

List

Redis 列表是简单的字符串列表,按照插入顺序排序,元素可以重复。

1
2
3
4
5
LINDEX key index 通过索引获取列表中的元素
LPOP key 移出并获取列表的第一个元素
RPOP key 移除最先插入的元素
LPUSH key value1 [value2] 将一个或多个值插入到列表头部
LPUSHX key value 将一个值插入到已存在的列表头部
  • 队列(lpop):右边进左边出
  • 栈(rpop):右边进右边出

Set

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

1
2
3
SADD key member1 [member2] 向集合添加一个或多个成员
SMEMBERS key 返回集合中的所有成员
SPOP key 移除并返回集合中的一个随机元素

ZSET

Redis 有序集合和集合一样也是 String 类型元素的集合,且不允许重复的成员。它是一个 Set,保证了内部 value 的唯一性,另一方面,它可以给每个 value 赋予一个 score,代表这个 value 的排序权重,在 score 相同的情况下,内部还会按照 value 的大小进行排序。它的内部实现用的是一种叫做「跳跃列表」的数据结构。

1
2
3
ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
ZCARD key 获取有序集合的成员数
ZRANK key member 获取成员位置

新增的一些新类型

HyperLogLog

HyperLogLog 是用来做基数统计的。HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的,因此每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 264 个不同元素的基数。
HyperLogLog 提供了两个指令 pfaddpfcount,根据字面意义很好理解,一个是增加计数,一个是获取计数。pfadd 用法和 set 集合的 sadd 是一样的,来一个用户 ID,就将用户 ID 塞进去。pfcount 和 scard 用法是一样的,直接获取计数值。
缺点:

  • 精确度。对于数据量大的时候,会出现精确度缺失。
  • HyperLogLog 这个数据结构不是免费的,不是说使用这个数据结构要花钱,它需要占据一定 12k 的存储空间,所以它不适合统计单个用户相关的数据。如果你的用户上亿,可以算算,这个空间成本是非常惊人的。但是相比 set 存储方案,HyperLogLog 所使用的空间那真是可以使用千斤对比四两来形容了。
1
2
pfadd key element [element ...] //增加
pfcount key [key ...] //统计

GeoHash

Redis 在 3.2 版本以后增加了地理位置 GEO 模块,意味着我们可以使用 Redis 来实现摩拜单车「附近的 Mobike」、美团和饿了么「附近的餐馆」这样的功能了。

1
2
3
4
5
6
7
8
9
   //添加
> geoadd company 116.48105 39.996794 juejin
> geoadd company 116.514203 39.905409 ireader
//计算距离,距离单位可以是 m、km、ml、ft,分别代表米、千米、英里和尺。
> geodist company juejin ireader km
// 获取元素位置
> geopos company juejin
//获取元素的 hash
> geohash key member

其他功能

Pub/Sub

订阅发布功能

Transaction(事务)

Redis 事务功能

Jedis

官网上推荐使用Jedis来操作Redis的。

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
//连接本地的 Redis 服务
Jedis jedis = new Jedis("localhost");
System.out.println("连接成功");
//设置 redis 字符串数据
jedis.set("key", "你好");
// 获取存储的数据并输出
System.out.println("redis 存储的字符串为: "+ jedis.get("key"));
}

不过,在平时开发中,我们一般都会基于Spring提供的Redis操作进行Redis。我自己练习的时候源码,有兴趣的话可以去下载来看看,这是一个基于springboot的项目,里面集成了很多东西。

客官,赏一杯coffee嘛~~~~