Redis学习1

Redis能干嘛

  1. Redis 官方数据 11W/秒读,8W/秒写,效率高
  2. 周期性的将数据写入磁盘做持久化。有两种方式:RDB、AOF
  3. 发布订阅系统,可以做消息队列
  4. 地图信息分析
  5. 计时器、计数器(浏览量)

特性

  1. 多样的数据类型
  2. 持久化
  3. 集群
  4. 事务

Redis基础知识

  1. Redis默认有16个数据库 ,默认第0个数据库,可以使用Select 命令切换 ;DBSize可以查看数据库大小; Keys * 可以查看所有的Key;flushall 清除全部 flushdb清除当前库

  2. Redis是单线程的

    Redis是很快的,Redis是基于内存操作的,CPU不是Redis性能瓶颈Redis的瓶颈是根据机器内存和网络带宽。既然可以使用单线程来实现,所以就使用了单线程。

  3. Redis为什么单线程还这么快

    1. 误区1:高性能的服务器一定是多线程

    2. 误区2:多线程(CPU上下文切换!)一定比单线程快

      CPU速度>内存速度>硬盘速度

      核心:Redis是将所有的数据全部放在内存中的,所以说使用单线程操作效率就是最高的。多线程(上下文切换:操作耗时!!),对于内存系统来说,如果没有上下文切换效率就是最高的!多次读写都是在一个CPU上。

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

Redis-Key

String

keys * #查看所有key

Set name Wayne #存值

get name #取值

EXISTS name  #检查name是否存在

move name #移除当前key

EXPIRE name 10 #设置过期时间,单位是秒

TTL name # 查看key的剩余时间

Type name # 查看类型

FlushALL #清空所有库

Append Name Zhang #追加字符串
################################################
incr views # views++
decr views # views--
incrby views 10 #views+10
decrby views 10 #views-10
################################################
#  setex 设置 key 多长时间过期
127.0.0.1:6379> setex cookie 30 username1
OK
127.0.0.1:6379> get cookie
"username1"
127.0.0.1:6379> ttl cookie
(integer) 22
127.0.0.1:6379> ttl cookie
(integer) 18
127.0.0.1:6379>
#setnx 如果没有才设置,有了就不设置了 (在分布式锁中会用)
127.0.0.1:6379> setnx ok ok
(integer) 1
127.0.0.1:6379> setnx ok notok
(integer) 0
127.0.0.1:6379> get ok

################################################
# mset 批量设置值
# mget 批量获取值
# msetnx 批量存值(如果有已经存在的,全不改)一起成功,一起失败
127.0.0.1:6379> mset k1 v1 k2 v2
OK
127.0.0.1:6379> mget k1 k2
1) "v1"
2) "v2"
127.0.0.1:6379> msetnx k4 v4 k1 v1
(integer) 0
127.0.0.1:6379> get v4
(nil)
127.0.0.1:6379> msetnx k4 v4 k1 v2
(integer) 0
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379> get k1
"v1"
################################################
# user:{id}:{filed}
################################################
#getset 先获取一个值在set一个值 
127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> getset db mongodb
"redis"
127.0.0.1:6379> get db
"mongodb"
127.0.0.1:6379>


String类型使用场景:Value除了是我们的字符串还可以是数字。

  • 计数器

  • 对象缓存存储

List

在Redis里面,我们可以把list完成栈、队列、阻塞队列

################################################
# lpush ,从左面push lrange ,取数组 0,-1 取所有 ,rpush,从右面push
127.0.0.1:6379> lpush list1 1 2 3 4 5
(integer) 5
127.0.0.1:6379> lrange list 0 -1
(empty list or set)
127.0.0.1:6379> lrange list1 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379> rpush list1 1 2 3 4 5
(integer) 10
127.0.0.1:6379> lrange list1 0 -1
 1) "5"
 2) "4"
 3) "3"
 4) "2"
 5) "1"
 6) "1"
 7) "2"
 8) "3"
 9) "4"
10) "5"
################################################
# lpop 从左面移除 rpop从右面移除
127.0.0.1:6379> lpop list1
"5"
127.0.0.1:6379> lrange list1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "1"
6) "2"
7) "3"
8) "4"
9) "5"
127.0.0.1:6379> rpop list1
"5"
127.0.0.1:6379> lrange list1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "1"
6) "2"
7) "3"
8) "4"
################################################
# llen 获取列表长度
127.0.0.1:6379> llen list1
(integer) 8
################################################
# lrem 移除指定的值
127.0.0.1:6379> lrange list1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "1"
6) "2"
7) "3"
8) "4"
127.0.0.1:6379> lrem list -1 4
(integer) 0
127.0.0.1:6379> lrange list1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "1"
6) "2"
7) "3"
8) "4"
127.0.0.1:6379> lrem list1 10000 4
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "3"
2) "2"
3) "1"
4) "1"
5) "2"
6) "3"
################################################
#rpoplpush
127.0.0.1:6379> lrange list1 0 -1
1) "3"
2) "2"
3) "1"
4) "1"
5) "2"
6) "3"
127.0.0.1:6379> rpoplpush list1 list2
"3"
127.0.0.1:6379> lrange list1 0 -1
1) "3"
2) "2"
3) "1"
4) "1"
5) "2"
127.0.0.1:6379> lrange list2 0 -1
1) "3"
################################################
#lset 更新值,不存在的index,就报超出索引的err了
127.0.0.1:6379> lpush list3 1
(integer) 1
127.0.0.1:6379> lset list3 1 2
(error) ERR index out of range

################################################
#linsert
127.0.0.1:6379> lpush list1 1 2 3
(integer) 3
127.0.0.1:6379> linsert list1 after 2 100
(integer) 4
127.0.0.1:6379> lrange list1 0 -1
1) "3"
2) "2"
3) "100"
4) "1"
################################################
#trim 修剪,有点像SubString
127.0.0.1:6379> lrange list1 0 -1
1) "3"
2) "2"
3) "100"
4) "1"
127.0.0.1:6379> ltrim list1 2 3
OK
127.0.0.1:6379> lrange list1 0 -1
1) "100"
2) "1"

小结

  • List实际是链表,Before Node after ,left right 都可以插入值
  • 如果key不存在,创建新的链表
  • 如果key存在,新增内容
  • 如果移除了所有值,空链表,也相当于不存在
  • 在两边插入或者改动效率最高,中间元素效率相对来说低

消息队列 Lpush Rpop

栈 Lpush Lpop

Set(集合)

set中的值不能重复

################################################
# sadd 添加 ,sismember 检查是否包含, scard 集合个数,smembers 显示所有成员,srem删除成员,sranmember 随机抽出一个数
127.0.0.1:6379> sadd myset 1
(integer) 1
127.0.0.1:6379> sadd myset 2
(integer) 1
127.0.0.1:6379> sadd myset 3
(integer) 1
127.0.0.1:6379> sismember myset 3
(integer) 1
127.0.0.1:6379> sismember myset 5
(integer) 0
127.0.0.1:6379> sadd myset 3
(integer) 0
127.0.0.1:6379> scard myset
(integer) 3
127.0.0.1:6379> smembers myset
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> srem myset 2
(integer) 1
127.0.0.1:6379> smembers myset
1) "1"
2) "3"
127.0.0.1:6379> smembers myset
1) "1"
2) "3"
127.0.0.1:6379> sadd myset 1 2 3 4 5 6 7
(integer) 5
127.0.0.1:6379> smembers myset
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
127.0.0.1:6379> srandmember myset
"6"
127.0.0.1:6379> srandmember myset 2
1) "6"
2) "4"
################################################
#sdiff 取 差集
#sunion取 并集
#sinter取 交集
127.0.0.1:6379> sadd k1 a b c d e
(integer) 5
127.0.0.1:6379> sadd k2 b c
(integer) 2
127.0.0.1:6379> sdiff k1 k2
1) "a"
2) "d"
3) "e"
127.0.0.1:6379> smembers k1
1) "b"
2) "a"
3) "d"
4) "c"
5) "e"
127.0.0.1:6379> sadd k2 f
(integer) 1
127.0.0.1:6379> sunion k1 k2
1) "d"
2) "c"
3) "b"
4) "a"
5) "f"
6) "e"
127.0.0.1:6379> sinter k1 k2
1) "b"
2) "c"

hash (哈希)

Map集合,key—map。本质和String没有太大区别

################################################
#hset , hmset ,hget ,hmget ,hgetall ,hdel , hlen
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hmset key myhash f2 v2 f3 v3
(error) ERR wrong number of arguments for HMSET
127.0.0.1:6379> hmset myhash f2 v2 f3 v3
OK
127.0.0.1:6379> hget myhash f2
"v2"
127.0.0.1:6379> hmget f2 f3
1) (nil)
127.0.0.1:6379> hmget myhash f2 f3
1) "v2"
2) "v3"
127.0.0.1:6379> hmget myhash f2 f2
1) "v2"
2) "v2"
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "hello"
3) "f2"
4) "v2"
5) "f3"
6) "v3"
127.0.0.1:6379> hdel myhash f2
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "hello"
3) "f3"
4) "v3"
127.0.0.1:6379> hlen myhash
(integer) 2
################################################
#HEXISTS
127.0.0.1:6379> HEXISTS myhash f3
(integer) 1
################################################
#hkeys hvals 获取所有key 获取vals 
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "f3"
127.0.0.1:6379> hvals myhash
1) "hello"
2) "v3"
################################################
#Hincr Hincrby Hdecr Hdecrby

ZSet(有序集合)

在Set的基础上,增加了一个值,用来排序

################################################
#zadd zadd zrange
127.0.0.1:6379> zadd zs 1 xiaotang
(integer) 1
127.0.0.1:6379> zadd zs 2 xiaona 3 zzy
(integer) 2
127.0.0.1:6379> zcard zs
(integer) 3
127.0.0.1:6379> zrange zs 0 -1
1) "xiaotang"
2) "xiaona"
3) "zzy"
################################################
#zrangebyscore 升序排序
127.0.0.1:6379> zrangebyscore zs -inf +inf withscores
1) "xiaotang"
2) "1"
3) "xiaona"
4) "2"
5) "zzy"
6) "3"
#zrevrangebyscore 降序排序 zrevrange
127.0.0.1:6379> zrevrangebyscore zs +inf -inf withscores
1) "zzy"
2) "3"
3) "xiaona"
4) "2"
5) "xiaotang"
6) "1"
127.0.0.1:6379> zrevrange zs 0 -1
1) "zzy"
2) "xiaona"
3) "xiaotang"
################################################
# count 取一共有几个(1<=count<=3)
127.0.0.1:6379> zcount zs 1 3
(integer) 3

事务

Redis单条命令保证原子性,但事务不保证原子性

Redis事务没有隔离级别的概念

Redis的事务:

  • 开启事务 multi
  • 命令入队 ...
  • 执行事务 exec
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) "v2"

Redis 实现乐观锁

################################################
#正常执行成功
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
################################################
# 执行失败 返回nil 多线程修改 
# 事务执行完注意解锁
127.0.0.1:6379> watch money out
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby money 20
QUEUED
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> unwatch
OK

视频学习资料:B站 狂神说

https://www.bilibili.com/video/BV1S54y1R7SB?p=1

posted @ 2020-11-16 21:51  花茶冰糖  阅读(132)  评论(0编辑  收藏  举报