1、redis概述和安装
1.1、安装redis
1. 下载redis 地址
https://download.redis.io/releases/
2. 将 redis 安装包拷贝到 /opt/ 目录
3. 解压
tar -zvxf redis-6.2.1.tar.gz
4. 安装gcc
yum install gcc
5. 进入目录
cd redis-6.2.1
6. 编译
make
7. 执行 make install 进行安装
8. 查看安装目录:/usr/local/bin
目录介绍
redis-benchmark:性能测试工具,可以在自己本子允许,看看自己本子性能如何
redis-check-aof:修复有问题的AOF文件,rdb和aof后面讲
redis-check-dump:修复有问题的dump.rdb文件
redis-sentinel:redis集群使用
redis-server:redis服务器启动命令
redis-clit:客户端,操作入口
1.2、启动redis
方式1:前台启动(不推荐)
执行 redis-server 命令,这种如果关闭启动窗口,则redis会停止。
方式2:后端启动(推荐)
后台方式启动后,关闭窗口后,redis不会被停止.
步骤如下
1. 复制redis.conf文件到/etc目录
cp /opt/redis-6.2.1/redis.conf /etc
2. 使用vi命令修改/etc/redis.config中的配置,将后台启动设置daemonize改为yes,如下
daemonize yes
3. 启动redis
redis-server /etc/redis.conf
- 查看redis进程
ps -ef|grep redis
1.3、关闭redis
方式1:kill -9 pid
方式2:redis-cli shutdown
1.4、进入redis命令窗口
执行 redis-cli 即可进入redis命令窗口,然后就可以执行redis命令了。
1.5、redis命令大全
地址:http://doc.redisfans.com/
文档地址 :
链接:https://pan.baidu.com/s/1XpefjEZlI6HIXe-5fkUkQg?pwd=03yi
提取码:03yi
2、redis 5大数据类型
这里说的数据类型是value的数据类型,key的类型都是字符串。
5种数据类型:
1. redis字符串(String)
2. redis列表(List)
3. redis集合(Set)
4. redis哈希表(Hash)
5. redis有序集合(Zset)
2.1、redis键(key)
1.keys :查看当前库所有的key
2. exists key: 判断某个key是否存在
3. type key: 查看你的key是什么类型
4. delkey:删除指定的key数据
5. unlink key:根据value删除非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的删除会在 后续异步中操作。
6. expire key 10:为指定的key设置有效期10秒
7. ttl key:查看指定的key还有多少秒过期,-1:表示永不过期,-2:表示已过期
8. select dbindex:切换数据库【0-15】,默认为0
9. dbsize:查看当前数据库key的数量
10. flushdb:清空当前库
11. flushall:通杀全部库
2.2、redis字符串(String)
2.2.1、简介
String是Redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。
String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg图片或者序列化的对象。
String类型是Redis最基本的数据类型,一个Redis中字符串value最多可以是512M
2.2.2、常用命令
1 . set:添加键值对
2 . get:获取值
示例
127.0.0.1:6379> set name ready
OK
127.0.0.1:6379> get name
"ready"
daemonize yes
3 . apend:追价值
append <key> <value>
将给定的value追加到原值的末尾。
示例
127.0.0.1:6379> set k1 hello
OK
127.0.0.1:6379> append k1 " world"
(integer) 11
127.0.0.1:6379> get k1
"hello world"
4 . strlen:获取值的长度
strlen <key>
示例
127.0.0.1:6379> set name ready
OK
127.0.0.1:6379> strlen name
(integer) 5
5 . setnx:key不存在时,设置key的值
setnx <key> <value>
示例
127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> setnx site "itsoku.com" #site不存在,返回1,表示设置成功
(integer) 1
127.0.0.1:6379> setnx site "itsoku.com" #再次通过setnx设置site,由于已经存在了,所以设
置失败,返回0
(integer) 0
6 . incr:原子递增1
incr <key>
将key中存储的值增1,只能对数字值操作,如果key不存在,则会新建一个,值为1
示例
127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> set age 30 #age值为30
OK
127.0.0.1:6379> incr age #age增加1,返回31
(integer) 31
127.0.0.1:6379> get age #获取age的值
"31"
127.0.0.1:6379> incr salary #salary不存在,自动创建一个,值为1
(integer) 1
127.0.0.1:6379> get salary #获取salary的值
"1"
7 . decr:原子递减1
decr <key>
将key中存储的值减1,只能对数字值操作,如果为空,新增值为-1
示例
127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> set age 30 #age值为30
OK
127.0.0.1:6379> decr age #age递减1,返回29
(integer) 29
127.0.0.1:6379> get age #获取age的值
"29"
127.0.0.1:6379> decr salary #salary不存在,自动创建一个,值为-1
(integer) -1
127.0.0.1:6379> get salary #获取salary
"-1"
8 . incrby/decrby:递增或者递减指定的数字
incrby/decrby <key> <步长>
将key中存储的数字值递增指定的步长,若key不存在,则相当于在原值为0的值上递增指定的步
长。
示例
127.0.0.1:6379> set salary 10000 #设置salary为10000
OK
127.0.0.1:6379> incrby salary 5000 #salary添加5000,返回15000
(integer) 15000
127.0.0.1:6379> get salary #获取salary
"15000"
127.0.0.1:6379> decrby salary 800 #salary减去800,返回14200
(integer) 14200
127.0.0.1:6379> get salary #获取salary
"14200"
9 . mset:同时设置多个key-value
mset < key1> < value1> < key2> < value2>
示例
127.0.0.1:6379> mset name ready age 30
OK
127.0.0.1:6379> get name
"ready"
127.0.0.1:6379> get age
"30"
10 . mget:获取多个key对应的值
mget < key1> < key2>
示例
127.0.0.1:6379> mset name ready age 30 #同时设置name和age
OK
127.0.0.1:6379> mget name age #同时读取name和age的值
1) "ready"
2) "30"
11 . msetnx:当多个key都不存在时,则设置成功
msetnx < key1> < value1> < key2> < value2>
原子性的,要么都成功,或者都失败。
示例
127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> set k1 v1 #设置k1
OK
127.0.0.1:6379> msetnx k1 v1 k2 v2 #当k1和k2都不存在的时候,同时设置k1和k2,由于k1已存
在,所以这个操作失败
(integer) 0
127.0.0.1:6379> mget k1 k2 #获取k1、k2,k2不存在
1) "v1"
2) (nil)
127.0.0.1:6379> msetnx k2 v2 k3 v3 #当k2、h3都不存在的时候,同时设置k2和k3,设置成功
(integer) 1
127.0.0.1:6379> mget k1 k2 k3 #后去k1、k2、k3的值
1) "v1"
2) "v2"
3) "v3
12 . getrange:获取值的范围,类似java中的substring
getrange key start开始索引 end结束索引
获取[start,end]返回为的字符串
示例
127.0.0.1:6379> set k1 helloworld
OK
127.0.0.1:6379> getrange k1 0 4
"hello"
13 . setrange:覆盖指定位置的值
setrange <key> <起始位置> <value>
示例
127.0.0.1:6379> set k1 helloworld
OK
127.0.0.1:6379> get k1
"helloworld"
127.0.0.1:6379> setrange k1 1 java
(integer) 10
127.0.0.1:6379> get k1
"hjavaworld"
14 . setrange:覆盖指定位置的值
setrange <key> <起始位置> <value>
从 起始位置替换指定字符
示例
127.0.0.1:6379> set k1 helloworld
OK
127.0.0.1:6379> get k1
"helloworld"
127.0.0.1:6379> setrange k1 1 java
(integer) 10
127.0.0.1:6379> get k1
"hjavaworld"
15 . setex:设置键值&过期时间(秒)
setex <key> <过期时间(秒)> <value>
设置 key的过期时间
示例
127.0.0.1:6379> setex k1 100 v1 #设置k1的值为v1,有效期100秒
OK
127.0.0.1:6379> get k1 #获取k1的值
"v1"
127.0.0.1:6379> ttl k1 #获取k1还有多少秒失效
(integer) 96
16 . getset:以新换旧,设置新值同时返回旧值
getset <key> <value>
示例
127.0.0.1:6379> set name ready #设置name为ready
OK
127.0.0.1:6379> getset name tom #设置name为tom,返回name的旧值
"ready"
127.0.0.1:6379> getset age 30 #设置age为30,age未设置过,返回age的旧值为null
(nil)
2.2.3、数据结构
String的数据结构为简单动态字符串(Simple Dynamic String,缩写SDS)。是可以修改的字符串,内
部结构上类似于Java的ArrayList,采用分配冗余空间的方式来减少内存的频繁分配。
如图所示,内部为当前字符串实际分配的空间capacity一般要高于实际字符串长度len。当字符串长度小
于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次会多扩容1M的空间。 要注意的是字符串最大长度为512M。
2.3、redis列表(List)
2.3.1、简介
单键多值 redis列表是简单的字符串列表,按照插入顺序排序。 你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
它的底层实际上是使用双向链表实现的,对两端的操作性能很高,通过索引下标操作中间节点性能会较 差。
2.3.2、常用命令
1 . lpush/rpush:从左边或者右边插入一个或多个值
lpush/rpush <key1> <value1> <key2> <value2> ..
示例
127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> rpush name java spring "springboot" "spring cloud" #列表name的左边
插入4个元素
(integer) 4
127.0.0.1:6379> lrange name 1 2 #从左边取出索引位于[1,2]范围内的元素
1) "spring"
2) "springboot
2 . lrange:从列表左边获取指定范围内的值
lrange <key> <star> <stop>
返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。 下标(index)参数 start 和 stop 都以
0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1
表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此 类推。 返回值: 一个列表,包含指定区间内的元素。
示例
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush course java c c++ php js nodejs #course集合的右边插入6个元素
(integer) 6
127.0.0.1:6379> lrange course 0 -1 #取出course集合中所有元素
1) "java"
2) "c"
3) "c++"
4) "php"
5) "js"
6) "nodejs"
127.0.0.1:6379> lrange course 1 3 #获取course集合索引[1,3]范围内的元素
1) "c"
2) "c++"
3) "php"
更
3 . lpop/rpop:从左边或者右边弹出多个元素
lpop/rpop <key> <count>
count:可以省略,默认值为1 lpop/rpop 操作之后,弹出来的值会从列表中删除 值在键在,值光键亡
示例
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush course java c++ php js node js #集合course右边加入6个元素
(integer) 6
127.0.0.1:6379> lpop course #从左边弹出1个元素
"java"
127.0.0.1:6379> rpop course 2 #从右边弹出2个元素
1) "js"
2) "node"
4 . rpoplpush:从一个列表右边弹出一个元素放到另外一个列表中
rpoplpush source destination
从source的右边弹出一个元素放到destination列表的左边
示例
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush k1 1 2 3 #列表k1的右边添加3个元素[1,2,3]
(integer) 3
127.0.0.1:6379> lrange k1 0 -1 #从左到右输出k1列表中的元素
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> rpush k2 4 5 6 #列表k2的右边添加3个元素[4,5,6]
(integer) 3
127.0.0.1:6379> lrange k2 0 -1 #从左到右输出k2列表中的元素
1) "4"
2) "5"
3) "6"
127.0.0.1:6379> rpoplpush k1 k2 #从k1的右边弹出一个元素放到k2的左边
"3"
127.0.0.1:6379> lrange k1 0 -1 #k1中剩下2个元素了
1) "1"
2) "2"
127.0.0.1:6379> lrange k2 0 -1 #k2中变成4个元素了
1) "3"
2) "4"
3) "5"
4) "6"
5 . lindex:获取指定索引位置的元素(从左到右)
lindex key index
返回列表 key 中,下标为 index 的元素。 下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0
表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2
表示列表的倒数第二个元素,以此 类推。 如果 key 不是列表类型,返回一个错误。 返回值: 列表中下标为 index 的元素。 如果
index 参数的值不在列表的区间范围内(out of range),返回 nil
示例
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush course java c c++ php #列表course中放入4个元素
(integer) 4
127.0.0.1:6379> lindex course 2 #返回索引位置2的元素
"c++"
127.0.0.1:6379> lindex course 200 #返回索引位置200的元素,没有
(nil)
127.0.0.1:6379> lindex course -1 #返回最后一个元素
"php"
6 . llen:获得列表长度
llen key
返回列表 key 的长度。
如果 key 不存在,则 key 被解释为一个空列表,返回 0 .
如果 key 不是列表类型,返回一个错误。
示例
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush name ready tom jack
(integer) 3
127.0.0.1:6379> llen name
(integer) 3
7 . linsert:在某个值的前或者后面插入一个值
linsert <key> before|after <value> <newvalue>
将值 newvalue 插入到列表 key 当中,位于值 value 之前或之后。
当 value 不存在于列表 key 时,不执行任何操作。
当 key 不存在时, key 被视为空列表,不执行任何操作。
如果 key 不是列表类型,返回一个错误。
返回值:
如果命令执行成功,返回插入操作完成之后,列表的长度。
如果没有找到 value ,返回 -1 。
如果 key 不存在或为空列表,返回 0
示例
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush name ready tom jack #列表name中添加3个元素
(integer) 3
127.0.0.1:6379> lrange name 0 -1 #name列表所有元素
1) "ready"
2) "tom"
3) "jack"
127.0.0.1:6379> linsert name before tom lily #tom前面添加lily
(integer) 4
127.0.0.1:6379> lrange name 0 -1 #name列表所有元素
1) "ready"
2) "lily"
3) "tom"
4) "jack"
127.0.0.1:6379> linsert name before xxx lucy # 在元素xxx前面插入lucy,由于xxx元素不存
在,插入失败,返回-1
(integer) -1
127.0.0.1:6379> lrange name 0 -1
1) "ready"
2) "lily"
3) "tom"
4) "jack"
8 . lrem:删除指定数量的某个元素
LREM key count value
**根据参数 count 的值,移除列表中与参数 value 相等的元素。
count 的值可以是以下几种:
count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
count < 0 : 从表尾开始向表头搜索,移除与value 相等的元素,数量为 count 的绝对 值
count = 0 : 移除表中所有与 value 相等的值。返回值: 被移除元素的数量。 因为不存在的 key 被视作空表(empty list),所以当 key 不存在时,总是返回 0 。**
示例
127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> rpush k1 v1 v2 v3 v2 v2 v1 #k1列表中插入6个元素
(integer) 6
127.0.0.1:6379> lrange k1 0 -1 #输出k1集合中所有元素
1) "v1"
2) "v2"
3) "v3"
4) "v2"
5) "v2"
6) "v1"
127.0.0.1:6379> lrem k1 2 v2 #k1集合中从左边删除2个v2
(integer) 2
127.0.0.1:6379> lrange k1 0 -1 #输出列表,列表中还有1个v2,前面2个v2干掉了
1) "v1"
2) "v3"
3) "v2"
4) "v1"
9 . lset:替换指定位置的值
lset <key> <index> <value>
将列表 key 下标为 index 的元素的值设置为 value 。 当 index 参数超出范围,或对一个空列表( key
不存在)进行lset时,返回一个错误。 返回值: 操作成功返回 ok ,否则返回错误信息。
示例
127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> rpush name tom jack ready #name集合中放入3个元素
(integer) 3
127.0.0.1:6379> lrange name 0 -1 #输出name集合元素
1) "tom"
2) "jack"
3) "ready"
127.0.0.1:6379> lset name 1 lily #将name集合中第2个元素替换为liy
OK
127.0.0.1:6379> lrange name 0 -1 #输出name集合元素
1) "tom"
2) "lily"
3) "ready"
127.0.0.1:6379> lset name 10 lily #索引超出范围,报错
(error) ERR index out of range
127.0.0.1:6379> lset course 1 java #course集合不存在,报错
(error) ERR no such key
2.3.4、数据结构
List的数据结构为快速链表quickList
首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也就是压缩列表。
它将所有的元素紧挨着一起存储,分配的是一块连续的内存。 当就比较多的时候才会改成quickList。
因为普通的链表需要的附加指针空间太大,会比较浪费空间,比如这个列表里存储的只是int类型的书,
结构上还需要2个额外的指针prev和next。
redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用,这样既满
足了快速的插入删除性能,又不会出现太大的空间冗余。
**
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>
setrange <key> <起始位置> <value>