一、Redis介绍及NIO原理介绍
1、常识介绍--磁盘、内存、IO
磁盘:
- 寻址:ms级别
- 带宽:G/M
内存:
-
寻址:ns级别
-
带宽:很大
秒>毫秒>微秒>纳秒 磁盘比内存在寻址上慢了10W倍!
I/O buffer:成本问题
- 磁盘与磁道,扇区,一扇区 512Byte,带来一个成本变大:索引;
- 操作系统,无论你读多少,都是以最少4K从磁盘拿!
2、数据存储发展过程
磁盘存储速度慢,内存速度快但是十分昂贵,于是我们选择一个折中的方案,使用缓存技术!
思考:数据库表很大,性能一定下降吗?
- 如果表有索引,增删改变慢!
- 查询速度视情况而定:
- 1个或少量查询依然很快(where后面的走索引,先从B+T找到树干,然后找到对应的叶子)。
- 并发大的时候会受硬盘带宽影响速度。
3、数据库引擎介绍
网站:db-engines.com
4、Redis 简单介绍
中文网址:redis.cn
英文网站:redis.io
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的五种数据结构:
memcached:k-v,value没有类型的概念,返回的是json;
为什么要选择Redis?
计算向数据移动:memcached会返回大量结果数据,然后在client解码;而Redis server直接根据类型的方法得到结果数据,将少量的数据返回给client!
5、Redis安装实操
1、环境:
- centos 6.x
- redis 官网5.x
6、Redis安装实操总结
步骤:
1.yum install wget
2.cd ~
3.mkdir soft
4.cd soft
5.wget https://download.redis.io/releases/redis-6.2.4.tar.gz
6.tar xf redis...tar.gz
7.cd redis-src
8.看README.md
9.make
...yum -y install gcc automake autoconf libtool make ...系统没有安装make、vim等常用命令,直接yum安装下即可
...yum install gcc
...make distclean
10.make
11.cd src ...生成了可执行程序
12.cd ..
13.make install PREFIX=/opt/mashibing/redis6
14.vi /etc/profile
...export REDIS_HOME=/opt/mashibing/redis6
...export PATH=$PATH:$REDIS_HOME/bin
...source /etc/profile
15.cd utils
16../install server.sh(可执行一次或多次)
a)一个物理机中可以有多个redis实例(进程),通过端口号port区分;
b)可执行程序就一份在目录,但是内存中未来的多个实例需要各自的配置文件,持久化目录等资源;
c)service redis_6379 start/stop/status > linux /etc/init.d/****
d)脚本还会帮你启动!
验证:ps -fe | grep redis
7、epoll介绍
8、Redis原理
思考:redis是单进程、单线程、单实例的,并发请求很多时怎么快速响应的呢?
- redis是基于内存的,内存的读写速度非常快!
- redis是单线程的,省去了很多上下文切换线程的时间!
- redis使用epoll多路复用技术,可以处理并发的连接!
二、Redis 的String 类
9、redis及NIO原理复习
10、redis 使用
-
redis-cli --默认端口号6379,redis-cli -p 指定端口号;
-
redis-cli一共有16个区域(库),每个库是隔离开的(数据不共享),使用select命令切换。
11、redis中value类型--字符串
-
操作字符串常用命令:
- SET
- GET
- STRLEN
- MSET
- MGET
- APPEND
- GETRANGE
- GETSET
-
help @string --使用help帮助命令,按tab键获取列表;
-
set k2 ooxx nx --如果不存在k2,则将其赋值为ooxx;
-
set k3 xoox xx --如果存在k3,则将其赋值为xoox;
12、redis中value类型--数值
- 常用的命令:
- getset
- incr 加一
- INCRBYFLOAT
- decr 减一
13、redis 二进制安全
14、redis中value 类型问题解决
15、redis 中value 类型--bitmap
-
常用的命令:
-
BITSET 这里参数是指二进制位的位置
-
BITCOUNT
-
BITPOS 这里参数start、end是指在哪个字节
-
BITTOP
-
16、redis中value类型--bitmap例一
-
有用户系统,统计用户登录天数,且窗口随机
SETBIT cary 1 1
SETBIT cary 7 1
SETBIT cary 364 1
STRLEN cary
BITCOUNT cary -2 -1
画图:
01 02 03 04 05 06 07 08 ...
cary 0 1 0 0 0 0 0 1
sean 1 1 0 1 0 0 0 1
17、redis 中value类型--bitmap例二
-
京东618活动,要统计仓库备货多少礼物,只发给系统活跃用户
SETBIT 20210601 1 1
SETBIT 20210602 1 1
SETBIT 20210602 7 1
BITOP or destkey 20210601 20210602
BITCOUNT destkey 0 -1画图:
u1 u2 u3 u4 ...
20210601 1 0 0 0
20210602 1 1 0 0
三、Redis 数据类型
18、redis中value类型--list
-
特征:list是有序的、元素可重复的。
-
常用命令:
-
LPUSH --压入一个或多个元素
-
LPOP --弹出且返回第一个元素
-
LRANGE --获取一个或多个元素
-
LINDEX --根据索引获取某个元素
-
LREM --删除元素(需要指定删除几个,因为list元素是可重复的)
-
LLEN --获取list长度(元素个数)
-
RPOP --弹出且返回最后一个元素
-
-
list支持阻塞,单播队列
-
现有三个客户端都连接了同一个redis的同一个端口,第一个客户端先连接端口6379,然后第二个客户端也连接端口6379,第三个客户端用来设置值。
-
第三个客户端第一次设置值的时候,第一个客户端先拿到值。
-
然后第三个客户端第二次设置值的时候,第二个客户端也拿到了值。
-
19、redis中value类型--hash
-
常用命令:
-
HSET --设置一个值
-
HGET --获取一个值
-
HMSET --设置多个值
-
HMGET --获取多个值
-
HKEYS --获取所有key
-
HVALS --获取所有value
-
HGETALL --获取所有key-value
-
HINCRBYFLOAT --小数加减
-
HINCRBY --整数加减
-
20、redis中value类型--set
-
常用命令:
- SADD --增加一个或多个元素
- SMEMBERS --获取所有元素
- SCARD --获取集合的元素数量
- SREM --删除一个或多个元素
- SINTER --对多个集合做交集操作
- SINTERSTORE --对多个集合做交集操作,并将结果存入一个key
- SDIFF --对多个集合做差集
- SREANDMEMBER --对多个集合做差集(保留在前面的集合元素),并将结果存入一个key
- SPOP --移除且返回一个或多个元素
-
随机事件(可用于抽奖):
命令格式:SREANDMEMBER key count
1、count为正数:取出一个去重的结果集,不能超过已有集;
2、count为负数:取出一个带重复的结果集,一定满足你要的数量;
3、count为0:不返回
-
场景一:现有3份奖品,5人参与抽奖,奖品小于人数,一次抽3个人,名字不能重复!
-
场景二:现有3份奖品,5人参与抽奖,奖品小于人数,一次抽3个人,名字可重复!
-
场景三:现有10份奖品,但是只有5人参与抽奖,奖品大于人数,要求多个人得多份奖品!
-
场景四:公司年会抽奖,一般每人只会中一次,故使用 SPOP 命令
-
21、redis中NIO问题解决
22、redis中value类型--sorted_set
-
特征:sortedSet元素有序不重复,物理内存左小右大,且不随命令发生变化!
-
拓展:sortedSet底层是用跳跃表实现的!
假设我要插入一个元素33,先在第一层发现33大于11,且11后面指向nil,继续看第二层,33大于22小于45,找到位置并插入。
网上查询,跳跃表长这样:
-
常用命令:
- ZADD --添加一个或多个元素
- ZRANGE(WITHSCORES) --根据索引范围获取元素(带分数)
- ZRANGEBYSCORE --根据分数区间获取元素
- ZREVRANGE(WITHSCORES) --从大到小获取元素(带分数)
- ZSCORE --获取某个元素的分数
- ZRANK --获取某个元素的索引
- ZINCRBY --加减元素的分数
- ZUNIONSTORE --多个集合求和/最值
四、Redis 进阶
24、redis管道(pipeline)的使用
管道(pipeline)可以一次性发送多条命令并在执行完后一次性将结果返回,pipeline 通过减少客户端与 redis 的通信次数来实现降低往返延时时间,而且 Pipeline 实现的原理是队列,而队列的原理是先进先出,这样就保证数据的顺序性。
25、redis 发布订阅的使用
在同一频道下,PUBLISH可以向通道发送消息,多个客户端可以通过SUBSCRIBE实时收到消息!
- 使用场景(一)
- 使用场景(二)
26、redis 事务的使用
-
命令
- MULTI --开启事务
- EXEC --执行所有指令
- DISCARD --开启事务后取消所有命令
- WATCH --监视队列里面待执行的所有key
- UNWATCH --忘记所有已监视的key
-
两个客户端都开启事务,第一个事务先执行删除,第二个事务再执行get会拿到一个空值,因为第一个事务已经删除成功了!