Redis笔记

一、入门

1、性能测试工具(redis-benchmark)

redis-benchmark 是Redis自身携带的测试工具,通过redis-benchemark命令,可以简单的对Redis做一个性能测试,方便我们更好体会到Redis的读写能力。

redis-benchmark -h localhost -p 6379 -c 100 -n 100000
即:100个并发连接,并且每个连接100000条请求,测试本地Redis性能

测试可选的参数及示意如下:

Benchmark参数字典

2、redis基础知识

redis有16个数据库,默认是第0个数据库,可以通过Select命令来切换数据库
在这里插入图片描述
同时可以通过dbsize命令,查看数据大小
通过keys *查看当前数据库下的所有Key

127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]> dbsize
(integer) 0
127.0.0.1:6379[3]> set name gaoms
OK
127.0.0.1:6379[3]> dbsize
(integer) 1
127.0.0.1:6379[3]> keys *
1) "name"
127.0.0.1:6379[3]> set age 18
OK
127.0.0.1:6379[3]> dbsize
(integer) 2

可以通过flushdb来清除当前数据库内容
通过flushAll清除所有数据库内容

127.0.0.1:6379[3]> keys *
1) "name"
2) "age"
127.0.0.1:6379[3]> flushdb
OK
127.0.0.1:6379[3]> keys *
(empty array)
127.0.0.1:6379[3]> select 0
OK
127.0.0.1:6379> keys *
1) "myhash"
2) "ke1"
3) "key:__rand_int__"
4) "mylist"
5) "name"
6) "counter:__rand_int__"
127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]> flushAll
OK
127.0.0.1:6379[3]> select 0
OK
127.0.0.1:6379> keys *
(empty array)

Redis 的默认端口是:6379(粉丝效应)

redis 是单线程的!

Redis是运行在内存上的,官方明确声明,CPU不是Redis的性能瓶颈,真正的性能瓶颈是内存的大小和网络带宽,既然可以使用单线程,那就使用单线程了,所以就使用了单线程。

Redis是用C语言编撰完成,官方数据100000+QBS,完全不必同样适用Key-value的memechache差。

Redis 为什么单线程还这么快?

误区1:高性能的服务器一定是多线程的。
误区2:多线程(CPU存在上下文切换),一定比单线程效率高。

Redis是运行在内存的数据库,数据库内容全部在内存上,使用单线程处理效率最好(减少因CPU上下文的切换,所耗费的时间),对于内存系统来说,如果没有上下文切换效率就是最高的,多次读写都在一个CPU上,是内存处理的最佳方案。

二、五大数据类型和三大特殊类型

Redis的官方介绍中,包含了支持的数据类型:
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-key

127.0.0.1:6379> keys *  #查看所有Key
(empty array)
127.0.0.1:6379> set name gaoms #设置key
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> move name 1 #移除当前key,1 -- 代表当前数据库的意思
(integer) 1
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set name gaoms
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> get name
"gaoms"
127.0.0.1:6379> expire name 10 # 设置过期时间,单位秒
(integer) 1
127.0.0.1:6379> ttl name #查看过期时间,单位秒
(integer) 7
127.0.0.1:6379> ttl name
(integer) 4
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> type age #判断Key对应Value的数据类型
string
127.0.0.1:6379> set name gaoms ex 15 #添加key,并设置超期时间
OK
127.0.0.1:6379> get name
"gaoms"
127.0.0.1:6379> ttl name
(integer) 8
127.0.0.1:6379> ttl name
(integer) 6
127.0.0.1:6379> ttl name
(integer) 4
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379>


Redis命令繁多,可以参考Redis帮助文档:http://www.redis.cn/commands.html#

在这里插入图片描述

String(字符串)

#######################################################################################################

#追加数据(Append)
127.0.0.1:6379> set key v1 #设置值
OK
127.0.0.1:6379> get key #获取值
"v1"
127.0.0.1:6379> keys * #查找所有的Key
1) "key"
127.0.0.1:6379> append key "zhangsan" #给key对应Value追加数据
(integer) 10
127.0.0.1:6379> strlen key #查看字符串长度
(integer) 10
127.0.0.1:6379> get key
"v1zhangsan"
127.0.0.1:6379> append name gaoms #当没有此key时,可等同于 set name gaoms
(integer) 5
127.0.0.1:6379> get name
"gaoms"
127.0.0.1:6379>
#######################################################################################################

#自增(incr, incrby),自减(decr,decrby)
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> get age
"18"
127.0.0.1:6379> incr age #自增1 ,等同与 i++
(integer) 19
127.0.0.1:6379> incr age #自增1 ,等同与 i++
(integer) 20
127.0.0.1:6379> get age
"20"
127.0.0.1:6379> decr age #自减1 ,等同与 i--
(integer) 19
127.0.0.1:6379> decr age #自减1 ,等同与 i--
(integer) 18
127.0.0.1:6379> incrby age 10 #可设置步长,设置增量,如例:自增10,等同于 age += 10
(integer) 28
127.0.0.1:6379> incrby age 10 #可设置步长,设置增量,如例:自增10,等同于 age += 10
(integer) 38
127.0.0.1:6379> decrby age 8 #可设置步长,设置增量,如例:自减8,等同于 age -= 8
(integer) 38
127.0.0.1:6379>

#由自增自减,key-value中的value既可以是String,也可以是 数字
#######################################################################################################

#截取字符串(getrange)
127.0.0.1:6379> set key1 helloMoto
OK
127.0.0.1:6379> getrange key1 0 3 #获取字符串(从0到3)
"hell"
127.0.0.1:6379> getrange key1 0 -1 ##获取字符串(从0到最后,-1代表最后的下标)
"helloMoto"
127.0.0.1:6379>

#替换字符串(setrange)
127.0.0.1:6379> set key1 abcdefg
OK
127.0.0.1:6379> setrange key1 1 xxx #从下标1开始向后替换字符串
(integer) 7
127.0.0.1:6379> get key1
"axxxefg"

#######################################################################################################

#setex(set with expire) 设置值,并携带过期时间
#setnx(set if not exist)设置值,当值不存在时
127.0.0.1:6379> setex name 20 gaoms #设置name,20s过期
OK
127.0.0.1:6379> ttl name #查看过期时间
(integer) 17
127.0.0.1:6379> get name
"gaoms"
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> set name zhans
OK
127.0.0.1:6379> setnx name lisi #当键存在时,设置失败
(integer) 0
127.0.0.1:6379> get name
"zhans"
127.0.0.1:6379> setnx age 20 #当键不存在时,设置成功
(integer) 1
127.0.0.1:6379> get age
"20"
127.0.0.1:6379>
#######################################################################################################

#批量获取(mget)
#批量设置(mset) -- msetnx(当键 都 不存在时,批量设置)
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #批量设置
OK
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> mget k1 k2 k4 
1) "v1"
2) "v2"
3) (nil)
127.0.0.1:6379> msetnx k1 v1 k4 v4 #当键都不存在时,批量设置,原子性(当其中有一个不成功,就都不能成功)
(integer) 0
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
3) "k3"
127.0.0.1:6379>
#######################################################################################################

#getset(先获取再设置)
127.0.0.1:6379> getset db redis #当键不存在,返回nil,并设置值
(nil)
127.0.0.1:6379> getset db MongoDb #当键存在,返回上一次设置的值,并设置值
"redis"
#######################################################################################################

用 String 类型可否插入对象?

以对象User{name:gaoms,age:20}为例:

#设计规则:{user}:{id}:{filed}
127.0.0.1:6379> mset user:1:name gaoms user:1:age 20
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "gaoms"
2) "20"
127.0.0.1:6379>

#字符串的灵活性很高,能很好的适配咱们得工作需要。

List(列表)

Redis提供了常见的List操作的命令和接口,通过这些方式,可以很好的应用到工作学习中(制作成:栈、队列等
List的命令中,除了分左右外,其他命令都以“L”开头。

#######################################################################################################

#List添加元素:Lpush(左侧),Rpush(右侧)
#List获取:LRange

127.0.0.1:6379> lpush list one #向List添加值(左侧)
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1 #获取list中的值(-1,代表最后的坐标)
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1 #指定坐标获取值,[0 ,1]
1) "three"
2) "two"
127.0.0.1:6379> rpush list xxx  #向List添加值(右侧)
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "xxx"
127.0.0.1:6379>
#######################################################################################################

#移除List元素:Lpop(左侧),Rpop(右侧)

127.0.0.1:6379> lpop list #从左侧移除一个元素
"three"
127.0.0.1:6379> rpop list #从右侧侧移除一个元素
"xxx"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lpop list 2 #从左侧移除两个元素(可以设置移除个数)
1) "two"
2) "one"
127.0.0.1:6379> lrange list 0 -1
(empty array)
127.0.0.1:6379>
#######################################################################################################

#根据下标获取List元素(lindex)
#获取List长度(llen)

127.0.0.1:6379> lpush list one two three four #批量设置元素
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "four"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lindex list 3 #查看下标为3的元素
"one"
127.0.0.1:6379> lindex list 2 #查看下标为2的元素
"two"
127.0.0.1:6379> lindex list 0 #查看下标为0的元素
"four"
127.0.0.1:6379> llen list #查看list的长度
(integer) 4
127.0.0.1:6379> rpop list 2
1) "one"
2) "two"
127.0.0.1:6379> llen list
(integer) 2
127.0.0.1:6379>
#######################################################################################################

#移除掉列表中的某个值(lrem)【如:取关操作】

127.0.0.1:6379> rpush list one two three three three three
(integer) 6
127.0.0.1:6379> lrange list 0 -1
1) "one"
2) "two"
3) "three"
4) "three"
5) "three"
6) "three"
127.0.0.1:6379> lrem list 1 one #移除1个one 元素(指定Value移除)
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "three"
3) "three"
4) "three"
5) "three"
127.0.0.1:6379> lrem list 2 three #移除2个three 元素(指定Value移除)
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "three"
3) "three"
127.0.0.1:6379>
#######################################################################################################

#裁剪,截断(ltrim)

127.0.0.1:6379> rpush list one two three four
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "one"
2) "two"
3) "three"
4) "four"
127.0.0.1:6379> ltrim list 1 2 #截取【1,2】的元素
OK
127.0.0.1:6379> lrange list 0 -1 #从结果上看,不光是截取,list中的元素已经变更为截取后的值了
1) "two"
2) "three"
127.0.0.1:6379>
#######################################################################################################

#删除一个元素,并追加到另一个列表中(RpopLpush)

127.0.0.1:6379> rpush list one two three four
(integer) 4
127.0.0.1:6379> rpoplpush list list2  #list移除最后一个元素,并追加到list2中去。
"four"
127.0.0.1:6379> lrange list 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> lrange list2 0 -1  #从list2看,list2已经被创建,并设置了移除的值
1) "four"
127.0.0.1:6379>
#######################################################################################################

#指定下标赋值(lset),相当于更新

127.0.0.1:6379> rpush list one
(integer) 1
127.0.0.1:6379> lset list 0 one2 #当列表中,此元素存在时,更新数据
OK
127.0.0.1:6379> lrange list 0 0
1) "one2"
127.0.0.1:6379> lset list 1 two #当列表中,此元素不存在时,报错
(error) ERR index out of range
127.0.0.1:6379>
#######################################################################################################

#插值(linsert)

127.0.0.1:6379> rpush list hello word
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "word"
127.0.0.1:6379> linsert list before word other #在“word” 前 插入值“other”
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "other"
3) "word"
127.0.0.1:6379> linsert list after other special #在“other” 后 插入值“special”
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "other"
3) "special"
4) "word"
127.0.0.1:6379>

在这里插入图片描述

Set集合(不可重复)

sadd --添加元素
smembers – 查看集合里所有元素
sismember – 查看集合是否含义该元素。
scard --元素个数
srem – 移除元素
srandmembert — 随机抽出一个元素
spop — 随机删除一个元素
smove — 移动指定元素到另一个集合中。
sdiff — 差集
sinter — 交集(共同关注)
sunion — 并集

Hash(哈希)

可看做map(key-value),与string类型没什么区别,只是将多个key-value放到集合中去。
hset – 设置1个元素
hmset — 设置多个元素
hget – 获取一个元素
hmget —获取多个元素
hgetall – 获取所有元素
hdel —删除指定元素(用可以来索引)
hlen – 获取长度
hexists — 判断元素是否存在
hkeys – 获取所有field(key)
hvals-- 获取所有value
hincrby – 自增
hdecrby --自减
hsetnx – 当不存在时,设置

Zset(有序集合)

在Set的基础上,设置一个值,Set k1 v1 ----- ZSet k2 score v2

zadd — 设置元素(可多个值)
zrange – 查询指定索引下的元素
zrangebyscore – 根据设置的Score 排序 (-inf 负无穷,+inf 正无穷)

>三大特殊类型

geospatial(地理位置)

底层实现是Zset,所以可以使用zrem移除一个元素

HyperLogLog(基数)

基数(不重复的值),类似网页UV值,有0.81%的错误率,因内存占用很小2^64,占用12KB,在可接受错误率的情况下,是很好的方案。

Bitmap(位图)

在这里插入图片描述

事务

Redis – 单条命令是保证原子性的,但是事务是不保证原子性的,会继续执行
(原子性:要么都成功,要么都失败)
redis事务本质:将要执行的命令,放入队列中,最后按照放入顺序执行(一次性,顺序性,排他性)

redis事务没有隔离级别的概念
所有命令在事务中,并没有直接执行,只有发起执行命令才会执行! exec

redis事务结构:
	开始事务(multi)
	命令入队(正常执行的命令)
	执行命令(exec)/放弃事务(discard)

编译型异常(代码有问题!命令有错),事务中所有的命令都不会执行
运行时异常(类似1/0),如果事务队列中有语法错误,在执行命令时,其他命令可以正常执行,错误命令会抛出异常

监控(Watch)

悲观锁:认为什么时间都会出问题,无论做什么都会加锁
乐观锁:认为神魔时候都不会出问题,所以不会加锁,更新数据时会判断一下在此期间是否有人修改过数据。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 32
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值