redis笔记
前言
Redis(Remote Dictionary Server)即远程字典服务
什么是redis?
Redis 是C语言开发的一个开源高性能键值对的内存数据库,可以用来做数据库、缓存、消息中间件等场景,是一种NoSQL(not-only sql,非关系型数据库)的数据库,也被人称为结构性数据库。
Redis能干嘛?
-
内存存储、持久化,内存断电即失,其持久化很重要(rdb、aof)
-
效率高,可以用于高速缓存
-
发布订阅系统(简单的消息队列)
-
地图信息分析
-
计数器、计时器(浏览量)
-
。。。
Redis特性
-
多样的数据类型
-
持久化
-
集群
-
事务
-
。。。
学习中需要用到的东西
-
官网:
-
中文网:
linux安装redis
-
下载安装包到Linux中
-
把压缩包移动到/opt中,解压安装包
tar -zxvf redis-7.2-rc3.tar.gz
-
进入解压后的文件可以看见配置文件,里面有redis.config
-
redis是c++编写的,所以Linux需安装c++环境,以下是安装环境
-
yum install gcc-c++
-
make
,make 是用来编译的,它从Makefile中读取指令,然后编译。 -
make install
这条命令来进行安装(有些软件要先运行 make check 或 make test 来进行测试) -
cd /usr/local/bin
进入默认安装位置 -
mkdir myconfig
创建一个个人的配置文件在redis的默认目录 -
cp /opt/redis-7.2-rc3/redis.conf myconfig
复制本来的redis.conf到个人配置文件 -
redis默认不是后台启动的,这里得修改配置文件,
daemonize no
中no改成yes即可 -
在/usr/local/bin目录启动redis服务,
redis-server myconfig/redis.conf
-
执行
redis-cli -p 6379
进行连接测试,连上就ping -
ps -ef|grep redis
查看开启的redis服务 -
关闭redis服务(关闭的是cli和server)操作,在客户端输入
shutdown
-
基础知识
数据库控制
-
redis默认有16个数据库,默认使用的是第0个,可以使用select进行切换
127.0.0.1:6379> select 3 ##切换数据库
OK
127.0.0.1:6379[3]> set name haohao2036 ##set操作
OK
127.0.0.1:6379> get name ##get操作
"haohao2036"
127.0.0.1:6379[3]> DBSIZE ##查看DB大小
(integer) 0
127.0.0.1:6379[3]> flushdb ##清空当前数据库
OK
127.0.0.1:6379[3]> flushall ##清空所有数据库
OK -
redis为什么是单线程的
redis是基于内存操作的,cpu不是redis的性能瓶颈所以就使用单线程了,其瓶颈是机器内存和网络带宽
-
redis为什么是单线程还这么快?
误区:
-
高性能的服务器一定是多线程?
-
多线程(CPU上下文切换会消耗资源)一定比单线程效率高?
redis是将所有数据全部放在内存中,所以说单线程效率是最高的,多线程cpu上下文切换反而会浪费资源
-
性能测试
官方给的redis-benchmark就是一个压力测试工具。
我们来简单地测试一下:100个并发连接,100000个请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
数据类型
Key的基本操作
keys * 查看所有key
set key value 创建key、value
get key 取得key的value值
dbsize 查看数据库大小
exists KEY 可以查看这个key存在多少个值
move KEY DB 移动key及其对应的value值到某个数据库
expire KEY SECONDS expire name 10
表示把让key为name的数据在10秒后过期(移除)
ttl KEY 查看当前key还有多少秒过期
type key 查看key的类型
五大基础数据类型
String(字符串)
String除了可以是字符串,还可以是数字、对象。
操作字符串
append KEY VALUE
和StringBuilder语法一样,追加字符串,就是往原先字符串后面再添加值
如果当前key不存在,就相当于set操作
例子如下:
127.0.0.1:6379[1]> get name
"hao2036"
127.0.0.1:6379[1]> append name 666
(integer) 10
127.0.0.1:6379[1]> get name
"hao2036666"
strlen KEY 获取key所在value的长度
getrange KEY 0 5 截取key的value索引从0到5的字符
setrange key 7 value 替换索引从7开始的字符
自增自减操作
(要求value是integer类型)
incr key 自增1
decr key 自减1
incrby key number key的value增加number
decrby key number key的value减少number
重要的set
getset
getset key value 组合操作先get再set
setex(set with expire)
setex KEY seconds value 创建一个 seconds秒过期的key-value
setnx(set if not exist)
setnx KEY VALUE 如果key不存在则创建一个key-value,如果存在就不覆盖
mset
mset KEY1 VALUE1 KEY2 VALUE2 KEY3 VALUE3 ... 批量创建key-value
mget
mget KEY1 KEY2 KEY3 ... 批量查询key-value
msetnx 批量执行setnx
msetnx k1 v666 k4 v4 如果key不存在则批量创建一个key-value,如果有一个存在就都不操作
对象的操作
常规操作:
set user:1 {name:zhangsan,age:23} 这里以json格式存储一个对象
get user:1 ##取出对象
另一种思路:
mset user:2:name lisi user:2:age 24 ##这里换种思路存储一个对象
mget user:2:name user:2:age ##取出对象
全部操作例子如下:
127.0.0.1:6379[1]> set num 0
OK
127.0.0.1:6379[1]> incr num ##自增1
(integer) 1
127.0.0.1:6379[1]> incr num
(integer) 2
127.0.0.1:6379[1]> get num
"2"
127.0.0.1:6379[1]> decr num ##自减1
(integer) 1
127.0.0.1:6379[1]> get num
"1"
127.0.0.1:6379[1]> incrby num 100 ##key的value增加100
(integer) 101
127.0.0.1:6379[1]> decrby num 50 ## key的value减少50
(integer) 51
127.0.0.1:6379[1]> get name
"hao2036666"
127.0.0.1:6379[1]> getrange name 0 5 ## 截取key的value索引从0到5的字符
"hao203"
127.0.0.1:6379[1]> getrange name 0 -1 ##截取全部字符(0到-1)
"hao2036666"
127.0.0.1:6379[1]> set name hao2036223666
OK
127.0.0.1:6379[1]> setrange name 7 hao ##替换索引从7开始的字符串
(integer) 13
127.0.0.1:6379[1]> get name
"hao2036hao666"
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> setex abc 30 'hello' ##创建一个30秒过期的key-value
OK
127.0.0.1:6379> ttl abc
(integer) 25
127.0.0.1:6379> setnx name1 111 ##setnx KEY VALUE 如果key不存在则创建一个key-value
(integer) 1
127.0.0.1:6379> get name1
"111"
127.0.0.1:6379> setnx name1 222 ##如果存在就不覆盖
(integer) 0
127.0.0.1:6379> get name1
"111"
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v666 k4 v4 ##批量使用setnx操作,它是原子性的,要么全部创建,要么都不创建
(integer) 0
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379> set user:1 {name:zhangsan,age:23}##这里以json格式存储一个对象
OK
127.0.0.1:6379> get user:1 ##取出对象
"{name:zhangsan,age:23}"
127.0.0.1:6379> mset user:2:name lisi user:2:age 24##这里换种思路存储一个对象
OK
127.0.0.1:6379> mget user:2:name user:2:age ##取出对象
1) "lisi"
2) "24"
List(列表)
在redis里面可以把list完成栈(一个入口,先进后出)、队列、阻塞队列(两端都可以取)
所有的list命令都是L开头的,虽然redis列表的尾部显式是1)开始,但索引从0开始,尾部为0
查元素及长度
LRANGE key start stop 查看索引从start到stop的list元素,当stop为-1时表示取到最先加入的元素为止
Lindex key Num 取索引为Num的元素
Llen key 返回列表的长度
添加和移除
LPUSH key value 往list加元素(加在尾部)
RPUSH key value 往list头部加元素
LPOP key 从尾部移除1个元素,如果key后接数字表示移除元素的个数
RPOP key 从头部移除1个元素
Lrem key Num Value 从尾部开始,去除num个值为value的元素
Linsert key before Value Value2 往列表key中元素value前(前表示靠近尾部)插入一个元素value2
Linsert key after Value Value2 往列表key中元素value后面插入一个元素value2
覆盖与修改
Ltrim key start stop 在key列表中,从尾部开始截取索引为start到stop的元素来覆盖该列表
Lset key Num value 修改key列表中索引是Num的元素,其结果改成value(Num处没有值则会报错)
多列表操作
RpopLpush key1 key2 移除列表key1头部一个元素并添加到列表key2尾部
全部操作例子如下:
127.0.0.1:6379> lpush list one
(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
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1 #可以发现先取出来的是后放进去的元素
1) "three"
2) "two"
127.0.0.1:6379> Rpush list zero
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "zero"
127.0.0.1:6379> LPOP list ##移除操作
"three"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
3) "zero"
127.0.0.1:6379> rpop list
"zero"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
#######################下面为重新的list
127.0.0.1:6379> lrange list 0 -1
1) "four"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lindex list 0 ##利用Lindex取元素
"four"
127.0.0.1:6379> lindex list -1 ##-1为头部
"one"
127.0.0.1:6379> Llen list ##返回列表的长度
(integer) 4
#########################
127.0.0.1:6379> lpush list one
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "one"
2) "four"
3) "three"
4) "two"
5) "one"
127.0.0.1:6379> lrem list 1 one ##移除列表中1个值为one的元素
(integer) 1
127.0.0.1:6379> lrange list 0 -1 ##可以发现Lrem是从尾部移除
1) "four"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lrem list 2 three ##移除数目超过存在的数目则会全部移除
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "four"
2) "two"
3) "one"
####################################
127.0.0.1:6379> ltrim list 0 1 ##在key为list的列表中截取索引为0到1的元素来覆盖list
OK
127.0.0.1:6379> lrange list 0 -1 ##可以看出截取也是从尾部开始的
1) "four"
2) "two"
########################
127.0.0.1:6379> RpopLpush list otherlist #移除list头部一个元素并添加到otherlist尾部
"one"
127.0.0.1:6379> lrange list 0 -1
1) "four"
2) "two"
127.0.0.1:6379> lrange otherlist 0 -1
1) "one"
############################
127.0.0.1:6379> lset list 0 six