1 Redis初识
1.1 Redis八大特性
Redis的键的类型是String的。
特性详解:
- 速度快:① 数据存储在内存中 ② 使用C语言编写(与系统融合性好)③ 单线程,避免资源争夺(
Redis6.0
之前是单线程的,Redis6.0
之后开始支持多线程)。 - 持久化:
redis
可以将内存中的数据异步保存到磁盘中,防止在断电等情况下的数据丢失。 - 支持多种数据类型:
String
、Hash
、linked List
、Set
、Sorted Set
- 支持多种编程语言:
Java
、Go
、python
、php
、Lua
、Node.js
、Ruby
- 功能丰富:发布订阅、
Lua
脚本、事务、pipeline
等 - 简单:源码的代码量少,可以修改。
- 支持主从复制:可为高可用、分布式提供便利。
- 高可用、分布式
1.2 redis使用场景
- 缓存系统
- 计数器
- 消息队列系统
- 排行榜
- 社交网络
- 实时系统
1.3 Docker安装redis
略
2 API的理解和使用
2.1 通用命令
keys
:查看所有的键 (keys *
:遍历所有的key
) 注意:keys
一般不在生产环境中使用,因为比较花销时间,会产生阻塞情况。dbsize
:计算key
的总数。exists key
:判断指定键是否存在。del key [key1 key2 ...]
:删除指定键的数据。expire key seconds
:给指定键设置过期时间(过期后自动删除)。ttl key
:查看key
的剩余过期时间。persist key
:去掉key
的过期时间。type key
:判断指定键的value
类型,返回结果String
、hash
、list
、set
、zset
、none
。- 时间复杂度:
keys
:O(n)
、dbsize
:O(1)
、del
:O(1)
、exists
:O(1)
、expire
:O(1)
、type
:O(1)
。 - 数据结构和内部编码:
string
:raw
、int
、embstr
;hash
:hashtable
、ziplist
;list
:linkedlist
、ziplist
;set
:hashtable
、intset
;zet
:skiplist
、ziplist
;
- 单线程:单线程为什么这么快?
- 纯内存。
- 非阻塞IO。
- 避免线程切换和竞态消耗。
- 单线程:
- 一次只运行一条命令。
- 拒绝长(慢)命令:
keys
,flushall
,flushdb
,slow lua script
,multi/exec
,operate
,big value(collection)
- 其实不是真正的单线程:
fysnc file descriptor
,close file descriptor
2.2 字符串(String)类型
使用场景:缓存、计数器、分布式锁 等等。
常用命令:
set
:设置key-value
时间复杂度O(1)
。get
:获取key
对应的value
时间复杂度O(1)
。del
:删除key-value
。incr key
:key
的值自增1,如果key
不存在,自增后get(key)
= 1。desc key
:key
的值自减1,如果key
不存在,自增后get(key)
= -1。incrby key k
:key
的值自增k,如果key
不存在,自增后get(key)
= k。desc key k
:key
的值自减k,如果key
不存在,自增后get(key)
= -k。set key
:不管key
是否存在,都设置 时间复杂度O(1)
。
setnx key
:key
不存在,才设置,相当于添加操作,时间复杂度O(1)
。
setxx key
:key
存在,才设置, 相当于更新操作,时间复杂度O(1)
。mset
:批量设置key-value
,时间复杂度O(n)
。例:mset key1 value1 key2 value2 key3 value3
mget
:批量获取key
,原子操作,时间复杂度O(n)
。例:mget key1 key2 key3...
getset key newvalue
:set key newvalue
并返回旧的value
,时间复杂度O(1)
。append key value
:将value
追加到旧的value
后面,时间复杂度O(1)
。strlen key
: 返回字符串的长度(注意中文的情况),时间复杂度O(1)
。incrbyfloat key
:以浮点数增加。getrange key start end
:获取指定起始索引的值。setrange key index value
:设置指定索引处的值。
2.3 哈希(Hash)类型
哈希命令是以字母h
为前缀,哈希键值结构,由key
(String
类型) field
(属性) value
(值)三部分组成,一个key
可以对应多个field-value
,可以把它看成一个对象。
特点:
Map-Map
即类似于map
嵌套了一个map
。Small redis
:相当于一个微小型的redis
。
常用命令:
hset
:(hset key field value
)设置hash
的key
对应的field-value
,时间复杂度O(1)
。hget
:(hget key field
) 获取hash key
对应的field
的value
,时间复杂度O(1)
。hdel
:(hdel key field
)删除hash key
对应的field
的value
, 时间复杂度O(1)
。hexists
:(hexists key field
)判断hash key
是否有field
, 时间复杂度O(1)
。hlen
:(hlen key
)获取hash key field
的数量 , 时间复杂度O(1)
。hmset
:(hmset key field1 value1 field2 value2 ...
)批量设置hash key
的field value
,时间复杂度O(n)
。hmget
:(hmget key field1 field2 field3 ...
)批量获取hash key
的field
对应的值,时间复杂度O(n)
。hgetall
: (hgetall key
) 返回hash key
对应的所有的field
和value
,时间复杂度O(n)
,注意小心使用hgetall
,牢记redis
是单线程的,使用hgetall
可能会造成阻塞现象。hvals
:(hvals key
)返回hash key
对应所有field
的value
,时间复杂度O(n)
。hkeys
:(hkeys key
)返回hash key
对应所有的field
,时间复杂度O(n)
。
2.4 有序列表(list)
列表是有序可以重复的,列表的左右两边插入弹出。
常用命令: 注意列表的命令是以 l-
为前缀。
rpush(rpush key value1 value2 ... valueN)
:从列表的右端插入(1 ~ N)
个值,时间复杂度O(1~n)
。
注意:push
时是从离键最近的值开始。lpush(lpush key value1 value2 ... valueN)
:从列表左端插入(1 ~ N)
个值,时间复杂度O(1~n)
。
注意:push时是从离键最近的值开始。linsert(linsert key before/after value newValue)
:在list的指定值的前或后插入新值 时间复杂度O(n)
。lpop(lpop key)
:从列表左侧弹出一个元素,时间复杂度O(1)
。rpop(rpop key)
:从列表右侧弹出一个元素,时间复杂度O(1)
。lrem(lrem key count value)
:根据count值,从列表中删除所有与value相等的元素,时间复杂度O(n)
。
- count > 0,从左到右开始删除最多
count
个与value
相等的元素。 - count <0,从右到左开始删除最多(
count
绝对值)个与value
相等的元素。 - count = 0,删除所有与
value
相等的元素。
ltrim(ltrim key start end)
:按照索引范围截取列表(将会只保留从指定索引开始到指定索引结束的子列表0,时间复杂度O(n)
。lrange(lrange key start end(包括end))
:获取列表指定索引范围内的所有元素,时间复杂度O(n)
。lindex(lindex key index)
:获取列表中指定索引的元素,时间复杂度O(n)
。
注意:当索引为-1
时表示是列表中最后一个元素。llen(llen key)
:获取列表长度(size),时间复杂度O(1)
。lset(lset key index newValue)
:修改列表指定索引处的元素为newValue
,时间复杂度O(n)
。blpop(blpop key timeout)
:从列表左端移出并获取列表第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。(lpop
阻塞版本,timeout
是阻塞超时时间,timeout = 0
表示永不阻塞),时间复杂度O(1)
。brpop(brpop key timeout)
:从列表右端移出并获取列表第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。(lpop
阻塞版本,timeout
是阻塞超时时间,timeout = 0
表示永不阻塞),时间复杂度O(1)
。
总结:
- lpush + lpop = Stack(实现栈)
- lpush + rpop = Queue(实现队列)
- lpush + ltrim = Capped Collection(实现固定集合)
- lpush + brpop = Message Queue(实现消息队列)
2.5 集合(Set)
集合的特点是元素是无序、不重复,支持集合间的操作(即两个集合取交集、并集、差集)。
常用命令:
注意集合的命令是以s-
为前缀;
sadd(sadd key value)
:向集合key
中添加value
,如果value
已经存在,则添加失败,时间复杂度O(1)
。srem(srem key value)
:将集合key
中的value
元素删除(删除元素的前提是知道集合中有此元素),时间复杂度O(1)
。scard(scard key)
:计算集合中有多少个元素。sismember(sismember key value)
:判断集合中是否存在值为value
的元素。srandmember(srandmember key count)
:从集合中随机挑count
个元素(集合中还有这些元素)。spop(spop key)
:从集合中随机弹出一个元素(弹出后集合中就没有此元素了)。smembers(smember key)
:获取集合中所有的元素。
注意:如果集合中的元素很多,因为redis
是单线程的,可能会发生阻塞现象,因此该命令应小心使用。sdiff(sdiff key1 key2)
:返回两个集合的差集(返回的是key1
中不在key2
中的元素)。sinter(sinter key1 key2)
:返回两个集合的交集(两个集合中共有的元素)。sunion(sunion key1 key2)
:返回两个集合的并集。sdiff|sinter|sunion +store destkey..
:将差集、交集、并集结果保存在destkey
中。
实际应用:
在社交应用中使用集合的交集就能找到共同关注的人。
2.6 有序集合(Sort Set)
有序集合不同于普通集合的是它有一个score
用来保持集合的有序性,有序集合的score
可以重复,但是集合中的元素仍保持不重复。
常用命令:
有序集合的命令是以z-
为前缀的。
zadd(zadd key score value,可以是多对score-value)
:向集合key
中添加score-value
,时间复杂度O(logN)
。zrem(zrem key value,可以是多个value)
:删除集合中的元素,可以一次删除多个,时间复杂度O(1)
zscore(zscore key value)
:返回元素的score
,时间复杂度O(1)
。zincrby(zincrby key score value)
:增加或减少元素的score
值,时间复杂度O(1)
。zcard(zcard key)
:返回元素的总个数,时间复杂度O(1)
。zrange(zrange key start end [withscores])
:返回指定索引范围内的升序元素(附带显示score
), 时间复杂度O(log(n)+m)
。zrangebyscore(zrangebyscore key minScore maxScore[withscores])
:返回指定score
范围内的升序元素(附带显示score
),时间复杂度O(log(n)+m)
。zcount(zcount key minScore maxScore)
:返回有序集合内在指定score范围内的元素个数 ,时间复杂度O(log(n)+m)
。zremrangebyrank(zremrangebyrank key start end)
:删除指定排名内的升序元素,时间复杂度O(log(n)+m)
。zremrangebyscore(zremrangebyscore key minScore maxScore)
:删除指定分数范围内的升序元素 ,时间复杂度O(log(n)+m)
。zrank(zrank key value)
:从小到大排列,返回索引。zrevank(zrevank key value)
:从大到小排列。与上面相反。zrevrange()
:与zrange
相反。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Go语言工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Go语言全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-7Z5WJpf7-1712985601529)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!