redis(五大数据类型)「建议收藏」

2022-09-21 20:55:35 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

Redis

  • Redis入门菜
  • Redis为什么这么快?
  • 五大数据类型
  • Zset

Redis可以用作数据库,缓存,消息中间件

Redis入门菜

redis 默认有16个数据库 可以使用select 进行切换数据库

代码语言:javascript复制
root@ubuntu:/usr/bin/redisconf# redis-cli 
127.0.0.1:6379> select 3 //选择第3个数据库
OK
127.0.0.1:6379[3]> DBSIZE	//查看数据库大小
(integer) 0
127.0.0.1:6379[3]> set name cc		//设置键值对
OK
127.0.0.1:6379[3]> get name		//获取键值对
"cc"
127.0.0.1:6379[3]> keys *	//查看所有key
1) "name"
127.0.0.1:6379[3]> flushdb		//删除对应数据库中所有key
OK
127.0.0.1:6379[3]> keys *
(empty list or set)
127.0.0.1:6379[3]> select 0	//选择第0号数据库
OK
127.0.0.1:6379> keys *		//查看所有key
1) "key:__rand_int__"
2) "counter:__rand_int__"
3) "name"
4) "mylist"
127.0.0.1:6379> flushALL		//清楚所有数据库的keys
OK
127.0.0.1:6379> select 2	//选择第二号数据库
OK
127.0.0.1:6379[2]> keys *		//查看所有的key
(empty list or set)

Redis为什么这么快?

官方答案:

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

现来聊一下什么是同步,异步,阻塞和非阻塞 同步和异步的概念描述的是用户线程与内核的交互方式:同步是指用户线程发起IO请求后需要等待或者轮询内核IO操作完成后才能继续执行;而异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

阻塞和非阻塞阻塞是指进程发起IO操作请求后需要彻底完成后才返回到用户空间;而非阻塞是指进程发起IO请求被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。

同步阻塞IO,同步非阻塞IO,多路复用IO技术

同步阻塞IO:同步阻塞IO模型是最简单的IO模型,进程在内核进行IO操作时被阻塞。 同步非阻塞IO:进程需要不断地调用read,如果有数据收到,就返回数据,如果没有数据收到,就立刻返回一个错误,让后进程再次read,直到这样是不会阻塞线程了,但是你还是要不断的轮询来读取或写入。 I/O多路复用 IO多路复用模型是建立在内核提供的多路分离函数select基础之上的,使用select函数可以避免同步非阻塞IO模型中轮询等待的问题。 线程首先将socket注册到select中,然后阻塞等待select系统调用返回,之后线程可以去做其他的事情。当数据到达时,socket被激活,select函数返回。用户线程正式发起read请求,读取数据并继续执行。使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还多了添加监视socket,以及调用select函数的额外操作,效率更差。但是,使用select以后最大的优势是用户可以在一个线程内同时处理多个socket的IO请求。用户可以注册多个socket,然后不断地调用select读取被激活的socket,即可达到在同一个线程内同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。

Redis快的原因

  • 完全基于内存:内存存储本来就比磁盘高
  • 不存在多进程或者多线程导致的切换而消耗CPU
  • 不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗
  • 使用多路I/O复用模型:多路I/O复用是用一个线程同时监察多个流的I/O事件的能力,在空闲时,会把前线程阻塞掉,在有一个或者是多个流有I/O事件的时候,就会从阻塞态当中唤醒,所以,程序就会轮询一遍所有的流,并且,依次顺序的处理就绪的流,这样做的话,就可以避免很多无用操作。(注意,这里的多路它所指的是多个网络连接,这里的复用指的是复用同一个线程。)

五大数据类型

String 常用命令

代码语言:javascript复制
127.0.0.1:6379[2]> keys *
1) "name"
2) "age"
127.0.0.1:6379[2]> exists name	//查看是否存在key
(integer) 1
127.0.0.1:6379[2]> move name 1	//复制name到数据库1中
(integer) 0
127.0.0.1:6379[2]> expire name		//设置name  key的到期时间

127.0.0.1:6379[2]> ttl name 	//查看name的到期时间
(integer) 7

127.0.0.1:6379[2]> type age	//查看类型
string

String

代码语言:javascript复制
127.0.0.1:6379[2]> keys *
1) "name"
2) "key1"
127.0.0.1:6379[2]> get name
"cc"
127.0.0.1:6379[2]> APPEND name 'hello world'	//追加字符,如果key不存在,则创建新的
(integer) 13
127.0.0.1:6379[2]> get name
"cchello world"
127.0.0.1:6379[2]> strlen name		//长度
(integer) 13

127.0.0.1:6379> set num 1
127.0.0.1:6379> INCR num	//自增’
127.0.0.1:6379> INCRBY num 10		//设置增加值
127.0.0.1:6379> decr num		//自减
127.0.0.1:6379> DECRBY num 10		//设置自减值

127.0.0.1:6379> set name cc_fendouing
127.0.0.1:6379> GETRANGE name 1 3
"c_f"
127.0.0.1:6379> SETRANGE name 2 xx	//replace
127.0.0.1:6379> get name
"ccxxendouing"

# setex (set with expire)	//设置过期时间
# setnx (set if not exist)	//不存在再设置	(分布式锁常使用)

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3	//同时创建多个key value
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
3) "k3"
127.0.0.1:6379> mget k1 k2 k3		//同时获得多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k6 v6		//是一个原子性操作,要么都成功,要么都失败
(integer) 0

# 对象
127.0.0.1:6379> mset user:1:name cc user:1:age 22	// user:{id}:{field}
127.0.0.1:6379> keys *
1) "user:1:age"
2) "user:1:name"

127.0.0.1:6379> getset name lish	//先获取再赋值

List 所有的list命令都是l开头的 List实际上是一个列表

代码语言:javascript复制
127.0.0.1:6379> LPUSH list one	//从左边push 
127.0.0.1:6379> Lpush list two
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> RPUSH list three	//从右边push
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
3) "three"
127.0.0.1:6379> LPOP list		//从左边弹出
127.0.0.1:6379> LINDEX list 1		//第一个值
127.0.0.1:6379> LLEN list		//长度
127.0.0.1:6379> LREM list 1 one		//从左边数删除1个名字为one的值

127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
3) "three"
127.0.0.1:6379> LTRIM list 1 2		//截取
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "one"
2) "three"

# rpoplpush list t_list		//组合操作  把list右边的值push到t_list 左边
# lset list 0 cc		//将列表中指定下标的值替换为另外一个值  指定的下表必须存在

# linsert list before 'cc' 'aa' # 在cc前面插入aa

Set Set中的值是不能重复的

代码语言:javascript复制
127.0.0.1:6379> sadd myset hello	//添加
(integer) 1
127.0.0.1:6379> sadd myset cc
(integer) 1
127.0.0.1:6379> sadd myset lisi
(integer) 1
127.0.0.1:6379> SMEMBERS myset		//查看set
1) "lisi"
2) "cc"
3) "hello"

127.0.0.1:6379> SISMEMBER myset cc	//查看是否存在
(integer) 1
127.0.0.1:6379> SCARD myset		//长度
(integer) 3
127.0.0.1:6379> SRANDMEMBER myset 2	//随机抽选两个元素
1) "hello"
2) "cc"
127.0.0.1:6379> SPOP myset		//随机删除
"cc"
127.0.0.1:6379> SMOVE myset t_myset lisi	将集和中的一个值移动到另外一个集和

127.0.0.1:6379> SDIFF set1 set2	//差集
127.0.0.1:6379> SInsert set1 set2		//交集
127.0.0.1:6379> SUnion set1 set2		//并集

Hash Map集和,key-map!这个value是一个map集合

代码语言:javascript复制
127.0.0.1:6379> HSET myhash field1 cc		//添加hash
(integer) 1
127.0.0.1:6379> hget myhash field1		//获取hash值
127.0.0.1:6379> HMset myhash field1 lisi field2 22		//批量设置
127.0.0.1:6379> HMGET myhash field1 field3		//批量获取
1) "lisi"
2) (nil)

127.0.0.1:6379> HMGET myhash field1 field3	//	获取全部key value
1) "lisi"
2) (nil)
127.0.0.1:6379> HLEN myhash		//长度
(integer) 2
127.0.0.1:6379> HEXISTS myhash field1		//是否存在字段
(integer) 1
127.0.0.1:6379> HSET myhash field3 1
(integer) 1
127.0.0.1:6379> HINCRBY myhash field3 2	//hash值增加
(integer) 3
127.0.0.1:6379> HSETNX myset field4 ee	//存在则创建,不存在则不创建

hash更适合对象存储

Zset

有序集合

代码语言:javascript复制
127.0.0.1:6379> zadd zset 1 one	//添加值
(integer) 1
127.0.0.1:6379> ZADD zset 2 tow
(integer) 1
127.0.0.1:6379> ZADD zset 3 three 4 four		//添加多个值
(integer) 2
127.0.0.1:6379> ZRANGE zset 0 -1
1) "one"
2) "tow"
3) "three"
4) "four"
127.0.0.1:6379> ZADD salary 100 cc
(integer) 1
127.0.0.1:6379> ZADD salary 200 lisi
(integer) 1
127.0.0.1:6379> ZADD salary 300 zhangsan
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf inf		//排序显示
1) "cc"
2) "lisi"
3) "zhangsan"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf inf withscores		//排序显示key value
1) "cc"
2) "100"
3) "lisi"
4) "200"
5) "zhangsan"
6) "300"

127.0.0.1:6379> ZREM salary cc	//移除
127.0.0.1:6379> ZCARD salary	//获取个数

# zrevrange salary //反转查看
# zcount count 1 3	//指定区间的成员数量

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/168802.html原文链接:https://javaforall.cn

0 人点赞