个人博客网:https://wushaopei.github.io/    (你想要这里多有)

内容:

  • 通用命令
  • 单线程架构
  • 数据结构和内部编码

一、常用的通用命令:

  • keys       计算所有的键
  • dbsize     获取redis的长度
  • exists key   判断键的存在与否
  • del key [key ...]    删除指定键的值
  • expire key seconds 对key做定时操作
  • type key

1、keys

1)用法1:

2)用法2:

说明 keys命令一般不在生产环境使用

2、dbsize:

3、exists:

4、del:

5、expire、ttl、persist

演示:

6、type:

7、命令的时间复杂度:

二、数据结构和内部编码

1、Redis的主要数据结构:

Redis的内部隐含结构体(对象): redis Object

2、该结构体包含以下数据类型及编码方式:

三、单线程

1、抽象理解Redis的单线程:

我们知道一个命令进入Redis执行的效率是很高的,在进入Redis之前可以认为它们在经过一条高速公路,如图中的黄色管道部分,而这条管道每一次都只能通过一个命令,多余的命令需要等待前面的命令执行完成后才能进入Redis中执行相应操作,也就是说,多个命令在操作Redis时是串行执行的。

2、单线程为什么这么快?

1)纯内存:

内存的响应速度是非常快的,内存的响应速度是100纳秒;也就是说Redis的速度高是依赖于内存的;

2)非阻塞IO

Redis中将equals和关闭、读写、连接转换为自己的一个事件,从而避免在网络IO上浪费过多的时间。

3)避免线程切换和竞态消耗

单线程equals模型

一瞬间只能执行一条命令

3、单线程:

1)一次只运行一条命令

2)拒绝长(慢)命令

Keys , flushall , flushdb , slow lua script , mutil / exec , operate big value ( collection )

3)其实不是单线程

fysnc file descriptor

close file descriptor

四、字符串

字符串:

  1. 结构和命令
  2. 快速实战
  3. 内部编码
  4. 查漏补缺

1、字符串键值结构

对于Redis来说,所有的key都是字符串,而它的value则是前面说过的五种类型。这里主要对Redis的value进行解析。当前的value为字符串类型

如上图,value是“world”,是一个字符串的类型

同样的,字符串的value也可以是一个数值类来表示

并且,字符串也可以做相应的转换,在字符串和整型间做转换,其原理类似于位图的使用。

① 字符串的value的表现形式也可以是以json的形式存在

② 字符串的value 最大限制为512MB的容量。

2、字符串的value的适用场景:

  • 缓存;
  • 计数器:例如:视频网站的视频的播放次数,每一次的播放会做加一的操作;
  • 分布式锁;
  • 等等。。。

3、字符串value的相关API操作:get、set、del、

其他的API的使用:Incr、decr、incrby、decrby:

4、演示:

5、实战

1)实战1:

实现如下功能:记录网站每个用户个人主页的访问量?

Incr userid : pageview (单线程:无竞争)

当用户的userid为123时, 以 incr 123:pageview的形式来进行自增,由于单线程执行,每个key都是一次执行的,不存在并发的问题,每次有新的访问就会提交一次 incr 123:pageview 的请求,依次累加达到访问量的计数。

2)实战2:

实现如下功能:缓存视频的基本信息(数据源在MySQL中)伪代码

如图,用户通过视频的id去获取视频的信息,首先会从App Server发起请求,App Server 会先从redis查询是否有匹配视频id的视频信息,如果redis中存在了,就直接返回给App Server,这就减少了数据库MySQL的压力;如果不存在,就会直接访问MySQL,从MySQL查询到了视频信息,就会回写到redis中,并同时返回给App Server。

下一次,用户访问接口或App Server时,依旧会从redis中访问,这无论是对应用的性能还是mysql减少压力都会有很大的优势。

伪代码实现:

首先,使用视频id和redisPrefix定义一个redis的key,然后从redis中获取key对应的 VideoInfo,再判断vaideoInfo如果为空,则从mysql中查询并返回对应视频id的视频信息 videoInfo;再次判断videoInfo 从mysql返回的结果不为空后进行序列化并set存入到redis 中。

3)实战3:

实现如下功能:分布式id生成器

比如我们有三个java的服务,我们希望每次获取到的id是自增的,并且是由三个服务去并发的获取,必须满足不重复又逐步递增。

解决方法:

       incr id (原子操作)

使用 incr 对共享的id进行操作,该操作由于原子性,可保证并发安全。

6、key 的设置命令:set  setnx  setxx

演示:

7、批量操作API:mget mset

演示:

8、延伸:

1)n次get

   nget = n次网络时间 + n次命令时间

由于大部分情况下,应用的客户端和服务端都处在不同的地区或机房,双方的信息交换即网络时间是一个很大的开销,而由于redis本身的优越性能,命令本身的开销是非常小的。

2)1次mget

1次mget = 1次网络时间 + n次命令时间

使用批量操作可以大大减少网络时间的消耗,有利于提高性能和效率。

9、Redis 的API : getset 、append、strlen

演示:

10、Redis 的API :incrbyfloat 、getrange、setrange

演示:

11、字符串总结:

五、 hash(1)

哈希:

  • 特点
  • 重要API
  • hash vs string
  • 查漏补缺

1、哈希键值结构:

如图:哈希的结构也是主要由键值结构组成,即key - value;但是其value是由 field 和 value 组成。

由于field属性的存在,与value构成了类似双列集合的结构,我们可以根据需要在相同的key ,即user:1:info 中添加一个field为viewCounter、value为50的值。

2、具体操作如下:

    add a new value

3、特点:

Mapmap:它的结构类似于一个包含了map的map;

Small redis: 由以上的mapmap结构可知,它就像包含了一个小的redis结构的redis

field不能相同,value可以相同:field类似于key ,每一个都是唯一的

4、相关API:hget 、hset、hdel

演示:

5、相关API: hexists 、hlen

演示:

6、API: hmget、hmset

演示:

六、hash(2)

1、实战:

1)实现如下功能:记录网站每个用户个人主页的访问量

具体实现:

    hincrby user:1:info pageview count

分析:

用user:1:info作为用户id,在用户的信息里面添加一个叫pageview的属性作为访问量的字段,这样可以让访问量的属性与用户信息成为一个整体,当有一个用户访问时,count为1,则访问量加1。

演示:

redis> HSET myhash field 5

(integer) 1

redis> HINCRBY myhash field 1

(integer) 6

redis> HINCRBY myhash field -1

(integer) 5

redis> HINCRBY myhash field -10

(integer) -5

2) 实现如下功能:  缓存视频的基本信息(数据源在mysql中)伪代码:

2、API:hgetall key、hvals key、hkeys key

演示:

小心使用hgetall,有redis是单线程的,使用hgetall取出多个信息的时候会有效率上的问题,即数据量过大时,如1万个value时,获取结果会很慢。

3、相似的API:

4、如何更新用户的属性:

1)使用字符串1:

将用户id作为key,并将用户属性及值的集合转换为json作为value保存到redis中;做更新操作时,根据用户id去取得所有的属性及值的json集合,由json格式转换为用户对象类型;对要修改的部分做增删改操作,将修改后的对象数据进行序列化,重新保存到对应用户idredis中,覆盖原来的value值。

2)使用字符串2:

如图中,将用户的信息根据用户id+属性名的方式进行拼接作为key,这样该用户的所有信息都是单独保存到redis中,在进行修改时只需要根据对应的key就可以进行修改了,将修改后的数据重新覆盖原来的信息。

同时的,在进行添加新的属性时,只需要按照key的规则进行单独添加即可。

3)使用hash:

用户信息(hash)

如图中,将用户的属性作为value的field,属性值作为vlue来进行添加到用户id作为key的redis中。更新用户信息时直接使用hset user:1:infor age 41 进行操作便可实现age的修改,同样也可以用来进行新增操作:如图中的link属性。

5、3种方案比较:

6、查漏补缺:

7、哈希总结:

七、 list(1)

列表:

  • 特点
  • 重要API
  • 实战
  • 查漏补缺

1、列表结构:

可以对列表做一些操作:如左边的添加、右边的添加、左边的弹出、右边的弹出

也可以获取列表的长度、删除指定元素、获取字列表、获取指定元素的索引值

2、特点:

  • 有序
  • 可以重复
  • 左右两边插入弹出

3、增——rpush

例如:使用rpush 向右边插入值 c b a

4、增——Ipush

例如:使用Ipush从右向左依次插入c b a

八、list(2)

1、增——linsert

例如:向值b的左边或右边插入值java或php

2、删——Ipop:

例如:从列表左侧弹出一个key ,弹出对象不需要指定,只需指定该列表listkey即可

3、删—— rpop:

例如:从列表右侧弹出一个key ,弹出对象不需要指定,只需指定该列表listkey即可

4、删——Irem :

例子:删除所有的a,从右到左删除1个c

5、列表修剪—— Itrim:

例如:第一次修剪索引1-4的值为:b(0)、c(1)、d(2)、e(3)

第二次修剪索引0-2的值为: b(0)、c(1)、d(2)、

Itrim在做一些大型列表的删除时是非常有用的,比如:一个列表有几百万,如果直接使用delkey的话会直接将redis阻塞掉,因为它的开销是非常大的。

而通过使用Itrim就可以通过每一个保留百万条、十万条、万条等等这样的方式去逐步的进行裁剪,从而达到删除的效果。

6、查——Irange:

例如:根据索引从左向右(0~5)或从右向左(-1~6)的查询

例如:保存0~2索引区间:a、bc、

保存1~-1索引区间:b、c、d、e、f

7、查—— lindex :

例如:获取索引为0的是a ;获取索引为-1的是f

8、查—— llen

例如:当前的长度是6

9、改 —— lset

例如:将索引为2的值改为java,即java覆盖值c

演示:

10、实战—— TimeLine

图中展示了微博的时间轴功能—— TimeLine,它会将微博按照从新到旧的功能进行排列,这和列表的功能是非常相似的。

假设图中的Your TimeLine是你微博的时间轴,如果你关注的用户有了更新,俺么该更新信息就会加入到时间轴的左上角,进入队列中。

在微博之中,包含了文字、图片、赞等等信息,可作为对象看待,存储的时候可以使用字符串或hash等等,而微博的id可以作为一个外联的key,这样就可以对微博的获取进行关联。

11、查漏补缺: -- blpop brpop:

12、总结:

①如果要实现一个栈的功能:

LRUSH + LPOP = Stack

②如果要实现一个堆的功能:

LRUSH +LPOP = Stack

③如果要控制一个有固定数量的列表,而不是让它无限制放大:

LPUSH + LTRIM = Capped Collection

④如果要实现一个消息队列的系统:

LPUSH + BRPOP = Message Queue

九、set

set:

  • 集合结构
  • 特点
  • 集合内API和实战
  • 集合间API和实战

1、特点:

  • 无序
  • 无重复
  • 支持集合间操作

2、增—— sadd srem :

工具—— scard 、sismember、srandmember、smembers、

注意: smembers 是无序且单线程的。

srandmember 和 spop:

  • spop 从集合弹出元素
  • srandmember不会破坏集合

演示:

3、实战

1)实战——抽奖系统:

以微博的抽奖为例,只要用户的量不是太大,可以把用户信息放入到集合中去,可以使用can be spop 进行弹出操作,在取出之后进行删除。

2)实战——标签(tag)

4、sdiff(差集) 、sinter(交集)、sunion(并集)

5、集合的使用场景:

1) SADD = Tagging                                                 做标签

2) SPOP/SRANDMEMBER = Random item            随机数

3) SADD + SINTER = Social Graph                         社交相关的场景

十、 zset

有序集合:

  • 特点
  • 重要API
  • 实战
  • 查漏补缺

1、有序结合的结构:

上图是有序集合的结构图,有序集合同样是有key-value键值结构的,但是它的value是由score和value构成的。它的有序是由score分值支持的,这与排序无关,所谓有序是指它的score是唯一的,并且由数值构成,意味着score的值是有序的。

2、集合和有序集合的对比:

3、列表和有序集合的对比:

4、增—— zadd :

例如:为id 为 user:1:ranking的用户添加一个score为225的element为tom的value

5、删—— zrem :

例如:删除id为user:1:ranking 的用户的score为225且element为tom的value

6、查—— zscore:

例如:获取有序集合中元素为tom的分数score 225.

7、自增或自减 —— zincrby:

例如:将元素为mike的分数增加9,达到100.

8、查个数——zcard :

例如:返回key为user:1:ranking 的元素的总个数

演示:

9、按照索引排名—— zrange :

例如:获取有序集合中索引为1到3的元素 mike 、frank、charis

10、按照分数排名——zrangebyscore :

例如:获取90分到123分的元素: mike 、frank

11、获取指定分数范围的元素个数—— zcount :

例如:获取200到210之间的个数: 2

12、按照排名范围进行元素的删除—— zremrangebyrank :

例如:删除集合中索引为1和2的元素

13、按照分值范围进行元素的删除 —— zremrangebyscore :

例如:将90到210间分数的元素删除

演示:

14、实战——排行榜 :

使用有序集合对新书榜单进行分数、销量、评价等进行排序。

15、有序集合总结:

Redis 入门到分布式 (二)API的理解和使用的更多相关文章

  1. Redis入门教程(二)

    推荐阅读: Redis入门教程(一)https://www.cnblogs.com/jichi/p/10285346.html 5. Redis 的数据结构 5.1 Redis 数据结构介绍 redi ...

  2. Redis入门指南之二(安装及配置)

    本节主要内容 1. 前言2. redis安装3. 启动和停止Redis 1. 前言 安装Redis需要知道自己需要哪个版本,有针对性的安装,比如如果需要redis GEO这个地理集合的特性,那么red ...

  3. Redis 入门到分布式 (一)Redis初识

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.Redis特性目录 Redis的特性: 速度快 持久化 多种数据结构 支持多种编辑语言 功能丰富 简 ...

  4. redis入门指南(二)—— 数据操作相关命令

    写在前面 以下绝大部分内容取材于<redis入门指南>,部分结合个人知识,实践后得出. 只记录重要,明确,属于新知的相关内容,杜绝冗余和重复. 字符串 1.字符串类型是redis中最常见的 ...

  5. Redis 入门到分布式 (四) 瑞士军刀Redis其他功能

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 目录: 慢查询 Pipeline 发布订阅 Bitmap(位图) HyperLogLog GEO 一.慢 ...

  6. Redis入门教程(二)— 基本数据类型

    阅读以下内容时,手边打开一个redis-cli一起输入,输入命令敲击回车键前在心中想好你的答案,如果结果不合你的预期,请分析原因,使极大地提高学习效率.如果没有条件,每个数据类型后有代码运行结果,供你 ...

  7. Redis 入门到分布式 (五) Redis持久化的取舍和选择

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) Redis持久化的取舍和选择 持久化的作用 RDB AOF RDB和AOF的选择 一.持久化的作用   ...

  8. webpack入门和实战(二):全面理解和运用loader和plugins

    您的阅读目录: 一.理解webpack加载器loader 二.理解less-loader加载器的使用 三.理解babel-loader加载器的使用 四.webpack命令行常见使用的操作 五.用web ...

  9. <Redis> 入门X 分布式锁

    分布式其实就是多进程的程序,当多个进程访问一个资源,会造成问题: 1.资源共享的竞争问题 2.数据的安全性 分布式锁的解决方案: 1.怎么去获取锁 数据库 zookeeper redis 2.怎么释放 ...

随机推荐

  1. GitHub上Asp.Net Core的源代码

    记录,备查. https://github.com/aspnet/AspNetCore/tree/master/src

  2. Directory类和DirectoryInfo类

    1.Directory类 Directory类公开了用于创建.移动.枚举.删除目录和子目录的静态方法 2.DirectoryInfo类 DirectoryInfo和Directory类的区别可以参看F ...

  3. 组合模式(c++实现)

    组合模式 目录 组合模式 定义 动机 UML类图 场景拆解 源码实现 优点 缺点 定义 将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式是的用户对单个对象和组合对象的使 ...

  4. 【Docker】在本地打包maven程序为docker镜像报错: Connect to localhost:2375 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1]

    错误信息: [ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.0.0:build (default-cli) on pr ...

  5. Linux 命令行下搜索工具大盘点,效率提高不止一倍!

    在 Linux 命令行下进行文本关键字的搜索,大家肯定第一时间会想到 grep 命令.grep 命令确实十分强大,但如果需要用到它更加灵活的功能时,可能命令就会显得十分复杂. 于是,为了简化 grep ...

  6. chmod的用法

    指令名称 : chmod 使用权限 : 所有使用者 使用方式 : chmod [-cfvR] [--help] [--version] mode file... 说明 : Linux/Unix 的档案 ...

  7. Navicat15 for Mysql激活教程

    1.下载Navicat Premium Navicat15链接:http://www.navicat.com.cn/download/navicat-premium,选择相应版本,这里选择window ...

  8. .net core BundlerMinifier.BundlerBuildTask 任务意外失败

    BundlerMinifier.BundlerBuildTask : 捆绑和缩小CSS.JS和HTML文件 BundlerMinifier.BundlerBuildTask 任务意外失败处理: 1.在 ...

  9. hibernate 异常分析:java.lang.NoClassDefFoundError: org/hibernate/Session

    原因: NoClassDefFoundError的含义就是说编译器找不到org/hibernate/Session这个类的定义 解决方法: 1.检查java中是否导入hibernate 包 impor ...

  10. python-基站位置查询

    本文采用的接口是聚合数据提供的 python2.7环境,3.x环境试了下好像不支持,获取位置信息为空 如下为运用代码: #coding=utf-8 ''' Created on 2019年9月18日 ...