redis学习笔记

Redis为什么是单线程,而6.0要引入多线程

看这篇文章的童鞋建议先去看我的io模型的那篇再回过头看这个
1,为什么redis是设计为单线程
其一是因为redis的设计是io多路复用,即使连接网络处理多io多路复用也可以在内存处理中被忽略
其二多线程模型虽然快但他不可保证执行顺序,并带来了并发读写的问题,
三是redis是基于内存的,多线程的是为了充分利用cpu资源.但对redis来说除了进行备份基本不会涉及到io操作数据读写,读写只发生在内存中,处理速度很快,所以使用多线程技术会很鸡肋
2为什么要引入多线程
read/write系统调用在执行期间占用了大量的cpu时间,将其网络读写总成多线程的方式会有很大性能提升,在其最新的几个版本中也加入了被其他线程异步处理的删除操作,因为redis的del命令删除元素特别大在短时间内不可完成,所以引入多线程来进行异步操作

redis命令

select 3 #切换数据库
keys * #查看所有的key
dbsize #查看数据个数
flushdb #清空当前数据库
flushall #清空所有数据库
exists name #判断name是否存在
expire name (second) #设置过期时间
ttl name #查看当前key的剩余时间
type name #查看当前key对应的value的数据类型
del name #删除

五种基础数据类型

String

key-value

set name zhangsan #设置字符串
append name zhangsan #字符串追加,如果key不存在相当于set key zhangsan
strlen name #获取字符串长度
incr name #相当于i++
incrby name #后面加步长
decr name #相当于i++
decrby name #后面加步长
getrange name start end #截取字符串从start到end,但end=0指到最后
setrange key offset value #替换字符串
setex name seconde value #设置值加过期时间
setnx name value #如果key不存在则创建(在分布式锁中常常使用)
mset k1 v1 k2 v2 k3 v3 #设置多个值
mget k1 k2 k3 #获取多个值
msetnx k1 v1 k2 v2 k3 v3 #如果key不存在则创建具有原子性,要么都成功要么都失败
getset k1 v1 #先获取k1对应的value,再set进去

list

key-index-value(index不用自己写,从左到右顺序的序号)

所有的list命令都是以l开头,redis的list是以栈的形式进行插入的

lpush list v1 v2 v3 #左边插入多个值
lpop list #弹出左边栈顶元素
rpush list v1 v2 v3 #右边插入多个值
rpop list #弹出右边栈顶元素
lrange list start end #从左开始获取
lindex list index #从左开始获取第index位置的数据,但index为-1时是获取最后一个值
llen list #获取list的个数
lrem list count value #移除list集合中值为value的count个数据
ltrim list start end #只要从start到end的数据
rpoplpush list list1 #弹出元素加入list1栈底
lset list index value #替换
linsert list after|before v value #将v插入再value之后|之前

set

key-member

sadd set v1 v2 v3 #添加多个值
sismember set v1 #查看是否包含
smembers set #查看所有值
scard set #获取set集合中value个数
srem set v1 v2 #移除元素
srandmember set (count) #随机指定count个数据,没有count则为一
spop set #随机弹出元素
smove set set2 value #将set中指定value移动到set2中
sdiff set1 set2 #求差集
sinter set1 set2 #求交集
sunion set1 set2 #求并集

hash

key-field-value

hset hash field value #存储数据
hget hash field #获取值
hmset hash f1 v1 f2 v2 #设置多个值
hmget hash f1 f2 #获取多个值
hgetall hash #获取所有值
hdel hash f1 f2 #删除指定的field
hlen hash #获取field个数
hexists hash filed #查看field是否存在
hkeys hash #获取所有的字段名
hvals hash #获取所有的value
hincrby hash field 1 #设置增量
hsetnx hash file value #如果不存在插入

zset

key-score-value

zadd zset 1 one 2 two #设置值
zrange zset 0 -1 #获取范围内的值
zrangebyscore set 200 600 #获取在最大值和最小值之间的数 inf代表无穷(infinite无限的)
zrangebyscore set 200 (600 #范围不包括600
zrangebyscore set 200 600 withscores #获取在最大值和最小值之间的数 inf代表无穷并获取score
ZREVRANGE set 0 -1 #倒叙
ZREVRANGEbyscore set 0 -1 withscores
zrem set zhangsan #移除zhangsan
zcard set #获取有多少个member
zcount set -inf +inf #获取score在最大和最小值之间的数

三种特殊数据类型

geospatial地理位置

只有六个命令

geoadd key 经度 纬度 member #添加地理信息
geopos key beijing shanghai #获取beijing和shanghai的经纬度
geodist key beijing shanghai #获取两个城市的直线距离(单位:m)
geodist key beijing shanghai km #获取两个城市的直线距离(单位:km)
georadius key 经度 纬度 len km #获取给定经纬度为半径的所有城市名称
GEORADIUS china 115 30 500 km withcoord withdist count 2 asc #withcoord 经纬度 withdist 距离 asc排序
georadiusbymember china beijing 500 km #以数据为中心
geohash china beijing #将经纬度变成长度为11的字符串若字符串越接近说明距离越短

底层是zset,可以用zset的方式操作geo

hyperloglog基数统计的算法

pfadd set1 a b #添加
pfcount set1 #获取set1中去重之后的个数
pfmerge set1 set2 #去两个并集的个数

Bitmaps位图

位存储,通过二进制进行存储

setbit sign 0 0 #存储数据
getbit sign 1 #获取当天的二进制
bitcount sign #获取1的个数

事务

redis单条命令保证原子性,但是redis的事务没有原子性

redis事务

  1. 开启事务(multi)
  2. 命令入队
  3. 执行事务(exec)

放弃事务(discard)

编译型异常:所有命令都不会执行

运行时异常:只有异常的命令不会执行,错误命令爆出异常

watch可以当乐观锁

原文地址:https://www.cnblogs.com/hfut/p/12989262.html