一、Redis概述
1、redis的安装
-
redis是使用c语言编写的安装redis之前需要有c的运行环境
-
查看当前是否有gcc的运行环境:
gcc --version
-
安装gcc
yum install gcc # 在线安装gcc
-
-
redis官网下载tar.gz压缩包,使用工具上传到 /opt目录下
-
使用解压命令将压缩包解压
tar -zxvf redis-6.2.1.tar.gz
-
进入到 redis-6.2.1/目录下,使用make命令编译
cd redis-6.2.1/ make
-
编译完成后使用make install 命令可以将redis安装完成
make install
-
-
redis安装完成之后,linux会将redis安装在 /usr/local/bin 目录下
cd /usr/local/bin
-
每个目录的意思
-
2、redis的启动
-
方式一:前台启动(不推荐)
redis-server # 启动之后可以使用ctrl+c退出
-
方式二:后台启动(推荐)
-
进入redis目录下拷贝一份redis.conf文件到任意目录下,这里选择 /etc/目录下
cp redis.conf /etc/redis.conf
-
打开/etc/目录下的redis.conf文件修改daemonize 的值 将no改为yes
vim redis.conf # 打开修改之后,设置可以后台启动
-
进入到redis的安装目录 /usr/local/bin 启动
cd /usr/local/bin # 进入到redis的安装目录 redis-server /etc/redis.conf # 通过指定redis配置文件的方式启动redis
-
这样启动之后,我们这样去查看是否启动完成
ps -ef|grep redis # 通过查看是否含有redis的进程
-
测试验证,使用使用redis-cli启动客户端后使用ping命令,若返回PONG则启动成功
[root@localhost bin]# redis-cli 127.0.0.1:6379> ping PONG
-
关闭redis服务器
shutdown #使用shutdown命令退出
-
3、redis基础知识
- redis默认有16个数据库,从0开始标号,默认使用0号库
- 命令 : select 12 可以切换到12号数据库
- 统一的密码管理,即16个库密码一致都是一样的
- redis是单线程 + 多路IO复用
- redis有五种常用的数据类型 : 字符串(String) 、列表(List) 、集合(Set) 、哈希(Hash) 、有序集合(Zset)
- redis中使用键值对(key-value)存储数据
4、rdis中的通用命令
命令语法 | 描述 |
---|---|
keys * | 查看当前库所有的key(匹配 : keys *1) |
exists key | 判断当前库中key是否存在 |
type key | 查看key是什么类型 |
del key | 删除指定key的数据 |
unlink key | 根据value选择非阻塞删除 (仅将key从keyspace元数据中删除,真正的删除操作会在后续异步操作) |
expire key second | 给指定的key设置过期时间(如: expire k1 10 表示k1 10秒后过期) |
ttl key | 查看key还有多少秒过期,-1表示永不过期,-2表示已经过期 |
select num | 切换数据库 |
dbsize | 查看当前数据库key的数量 |
flushdb | 清空当前库 |
flushall | 清空全部的库 |
5、redis字符串(String)
-
String是redis最基本的类型,String是二进制安全的,意味着redis中的String可以包含任意数据(如:.jpg图片或序列化的对象),一个redis中的字符串最多可以是512M
-
常用命令
命令语法 描述 set key value
setnx key value
setex key second value设置key-value,若key已经存在则覆盖
* 只有在key不存在的时候才会设置key的值
* 设置键值的同时,设置second秒后过期get key
getset key value获取key对应的value值
* 使用value替换掉key原来的value值,并且获取原来的value值append key value 将给定的value追加到原值的末尾 strlen key 获取值的长度 incr key 将key存储的值 + 1
(只能对数字值操作,否则报错,如果key为空,新增值为1)decr key 将key存储的值 - 1
(只能对数字值操作,否则报错,如果key为空,新增值为-1)incrby / decrby key step 将key中存储的数字值按照指定step(步长)增加或减少 mset k1 v1 k2 v2 … 同时设置一个或多个key-value键值对 mget k1 k2 … 同时获取一个或多个key对应的value值 msetnx k1 v1 k2 v2 … 同时设置一个或多个key-value,当且仅当所有给定的key都不存在时 getrange key begin end 获取值的范围,类似java中的substring()方法,包括前,包括后 setrange key begin value 使用value从begin索引位置开始覆盖字符串值 -
注意事项
-
原子性:不会被线程调度机制打断的操作(即:操作一旦开始,就一直运行到结束,中间不会有任何线程切换的过程(context switch))
-
redis的单线程可以认为redis的命令都是原子性的,单条指令都可以认为是"原子操作",以为终端只能发生于指令之间
-
对于上述命令中的m开始的命令语法,批量操作的都可以认为是原子操作(即: 任意一个是失败,整条命令都失败)
-
思考: 对于java中 ++ 操作是否是原子操作?
答: 不是,例如 : i = 0 ,两个线程同时操作 i++,执行100次那 i 的值会是多少? 2 - 200之间的值都有可能(包括 2 和 200 )
-
-
String的底层数据结构
- String的数据结构为简单动态字符串(Simple Dynamic String,SDS)。是可以修改的字符串,内部结构的实现上有点类似与java中的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配,内部为当前字符串实际分配的控件一般要高于实际字符串的长度,当字符串长度小于1M时,扩容都是加倍于现有的空间如果超过1M,扩容时一次只会多扩容1M的空间(注:字符串的最大长度为512M)
6、redis列表(List)
-
List是简单的字符串列表,按照插入顺序排序,底层实际上是一个双向链表,对两端的操作性能很高,通过索引下标操作中间节点性能较差
-
常用命令
命令语法 描述 lpop/rpop key 从左边/右边删除一个值,并返回该值 lpush/rpush key value1 value2 … 从左边/右边插入一个或多个值 rpoplpush key1 key2 从key1列表右边删除一个值,插入到key2列表左边 lrange key start stop
lrange key 0 -1从左到右获取start到stop下标的元素
表示获取key列表的全部元素(0:左边第一个,-1:右边第一个)lindex key index 按照指定index索引获取key列表的元素(从左到右) llen key 获取key列表的长度 linsert key before value newValue 在key列表的value元素的前面插入newValue元素 linsert key after value newValue 在key列表的value元素的后面插入newValue元素 lrem key n value 从左边删除key列表中n个值为value的元素 lset key index value 将列表key下标为index的值替换为value元素 -
List的底层数据结构
- 首先在列表元素较少的情况下会使用一块连续的内存空间,这个结构是ziplist,它将所有的元素紧挨着一起存储,分配的是一块连续的内存,当数据量比较多的时候才会改成quicklist,因为普通的链表需要附加指针占用空间太大,浪费空间,redis中将链表和ziplist结合了起来,组成了quicklist,也就是将多个ziplist使用双向指针串起来使用,这样既满足了快速的插入删除性能,又不会出现太大的控件冗余
7、redis集合(Set)
-
Set对外提供的功能与list类似,不同在于Set是不能存放重复元素的,当不希望存储重复元素的时候是一个很好的选择,Set是String类型的无序集合,次鞥是一个value为null的Hash表,所以添加、删除、查找的复杂度都是O(1)
-
常用命令
命令语法 描述 sadd key value1 value2 … 将一个或多个member元素添加到集合key中
(已经存在的member元素将被忽略)smembers key 取出该集合的所有值 sismember key value 判断集合key是否包含value元素(包含返回1,否则返回0) scard key 返回该集合的元素个数 srem key value1 value2 … 删除集合key中的一个或多个元素 spop key 随机删除集合key中的一个元素,并返回值 srandmember key n 随机从集合key中取出n个元素,不会将元素删除 smove sourceKey destKey value 将集合sourceKey中的value元素移动到destKey集合中 sinter key1 key2 返回key1和key2集合的交集元素 sunion key1 key2 返回key1和key2集合的并集元素 sdiff key1 key2 返回key1和key2集合的差集元素 -
数据结构
- Set的数据结构是dict字典,字典是用哈希表实现的,Set的结构使用hash结构,所有的value都指向同一个内部值
8、redis哈希(Hash)
-
Hash是以个键值对集合,Hash是一个String类型的field和value的映射表,Hash特别适合用于存储对象
-
常用命令
命令语法 描述 hset key field value 给key集合中的field键赋值value hget key field 从key集合中取出field对应的value值 hmset key field1 value1 field2 value2 … 批量给key集合设置值 hexists key field 查看哈希表key中,给定域field是否存在(存在1,不存在0) hkeys key 列出key哈希集合的所有field hvals key 列出key哈希集合的所有value hincrby key field increment 为哈希表key中的域field的值加上增量increment hsetnx key field value 将哈希表key中的域field的值设置为value,当且仅当field不存在 -
数据结构
- Hash类型对应的数据结构是两种:ziplist(压缩列表)和hashtable(哈希表),当field-value的长度较短且个数较少时,使用ziplist,否则使用hashtable
9、redis有序集合(Zset [Sorted Set])
-
有序集合Zset与普通集合Set非常相似,是一个没有重复元素的字符串集合,不同之处在于有序集合的每一个成员都关联了一个评分(score),这个根据score排序集合中的成员,集合的成员是唯一的,但是评分(socre)是可以重复的
-
常用命令
命令语法 描述 zadd key score1 value1 socre2 value2 … 将一个或多个member元素及其score值加入到有序集合key中 zrange key start stop [withscores] 返回有序集合key,索引在start和stop之间的元素,
若带上withscores可以将分数一块返回zrangebyscore key min max [withscores] [limit offset count] 返回有序集合key中所有score值介于min和max之间(包含min和max)的成员,有序集合按照score值递增排序 zrevrangebyscore key max min [withscores] [limit offset count] 同上,但是是从大到小排序 zincrby key increment value 为元素的score加上增量 increment zrem key value 删除key集合下指定value的元素 zcount key min max 统计该集合score 在min max区间内的元素个数 zrank key value 返回该值再集合中的排名,从0开始 -
数据结构
- Zset底层使用了两种数据结构
- hash,hash的作用就是关联元素value和权重score,保证元素value的唯一性,可以通过元素value找到对应的score值
- 跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表
- Zset底层使用了两种数据结构