尚硅谷Redis6从入门到精通(上)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 尚硅谷Redis6从入门到精通

1. NoSQL数据库简介


Not Only SQL,非关系型数据库


NoSQL有什么用:


  1. 解决CPU和内存压力


  1. 解决IO压力


NoSQL数据库特点:


  1. 非关系型数据库,不依赖业务逻辑数据库存储,以key-value存储,因此大大增加了数据库的扩展能力


  1. 不遵守SQL标准


  1. 不支持ACID(原子性、隔离性、一致性、持久性)


  1. 远超于SQL的性能


适用于:


  1. 高并发读写


  1. 海量数据读写


  1. 数据可扩展


不适用于场景:


  1. 需要事务支持


  1. 需要基于SQL结构化查询存储


NoSQL优点:


  1. 缓存数据库,完全在内存中,速度快,数据结构简单


  1. 减少io操作,数据库和表拆分,虽然破坏业务逻辑,即外加一个缓存数据库,提高数据库速度,也可以用专门的存储方式,以及针对不同的数据结构存储


常见的NoSQL数据库


  1. Memcache:不支持持久化


  1. Redis:支持持久化


  1. MongoDB:文档数据库



2. Redis安装与配置


0. Redis概述


redis特性:


  • Redis是一个开源的key-value存储系统


  • 支持string,list,set,zset,hash类型


  • 这些数据类型都支持push/pop,add/remove,取交集并集等,这些操作都是原子性的


  • 支持不同方式的排序


  • 数据都是缓存在内存中


  • 实现了主从同步


1. 下载与安装


下载网址:Redis,只支持Linux版本,下载后在Ubuntu下解压,切入到对应文件夹下

首先需要gcc运行环境


sudo apt install gcc
gcc --version    //查看gcc版本


安装Redis:


make 
sudo make install


判断是否安装成功:



安装目录:/usr/local/bin


查看默认安装目录:


  • redis-benchmark:性能测试工具


  • redis-check-aof:修复有问题的 aof文件


  • redis-check-dump:修复有问题的dump.rdb文件


  • redis-sentinel:Redis集群使用


  • redis-server:Redis服务器启动命令


  • redis-cli:客户端,操作入口


2. 运行


a. 前台启动方式


(不推荐)


打开了就不问关闭该终端


cd /usr/local/bin
redis-server



b. 后台启动方式


把终端断掉了后台还在运行redis


cd redis-6.2.6   //切入Redis的文件夹
cp redis.conf etc/redis.conf  //拷贝一份redis.conf
cd /etc/
gedit redis.conf
//查找daemo  修改后面的no->yes
redis-server /etc/redis.conf  //后台启动redis服务器端



查看是否在运行:




退出方法


exit或关闭后台redis-cli shutdown或关闭进程号 kill -9 进程号

总结:以后这样登录redis:/usr/local/bin/redis-cli



3. set插入数据报错解决方法


参考博客:


https://blog.csdn.net/Sophia_0331/article/details/107779165


https://blog.csdn.net/zdyueguanyun/article/details/83449912



解决方法:


config set stop-writes-on-bgsave-error no


3. 常用五大数据类型


0. Redis相关知识


  • 登录redis:/usr/local/bin/redis-cli


  • Redis端口:6379


  • Redis默认0号数据库


  • Redis是单线程+多路IO复用



1. key


数据的操作:


  • 插入数据:set key value


  • 查看当前库的所有key:keys *


  • 是否存在当前键:exists key,存在返回1,否则返回0


  • 删除键值对:del key


  • 删除键值对:unlink key ,选择非阻塞删除


  • 查看键对应的值的类型:type key


  • 给键设置过期时间:expire key time,time以秒为单位


  • 查看键多长时间过期:ttl key,-1表示永不过期,-2表示已过期


zdb@zdb-virtual-machine:~$ /usr/local/bin/redis-cli
127.0.0.1:6379> keys *
(empty array)
//插入数据
127.0.0.1:6379> set k1 lucy
OK
127.0.0.1:6379> set k2 mary
OK
127.0.0.1:6379> set k3 jack
OK
//查询数据
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"
127.0.0.1:6379> exists k1
(integer) 1
127.0.0.1:6379> exists k4
(integer) 0
127.0.0.1:6379> type k1
string
//删除数据    
127.0.0.1:6379> del k3
(integer) 1
127.0.0.1:6379> unlink k2
(integer) 1
//设置定时器    
127.0.0.1:6379> expire k1 10
(integer) 1
127.0.0.1:6379> ttl k1
(integer) 4
127.0.0.1:6379> ttl k1
(integer) -2


库的操作:


  • 选择库:select 库号,默认库为0号


  • 查看当前数据库的key数量:dbsize


  • 清空当前库:flushdb


  • 清空所有库:flushall


127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> dbsize
(integer) 0
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> flushdb
OK


2. string


关于string的介绍:


  • 一个key对应一个value


  • 二进制安全的,string可包含任何数据,比如jpg图片转换成string存储


  • value最多可以是512M


  • 动态的字符串,会扩容


常用命令:


  • 获取值:get key


  • 在值尾部追加元素:append key add_value


  • 获取值的长度:strlen key


  • 当key不存在,才存入key-value对:setnx key value


  • value增1:incr key


  • value减1:decr key


  • value增一个常数:incrby key 步长


  • value减一个常数:decr key 步长


127.0.0.1:6379> set k1 v100
OK
127.0.0.1:6379> set k2 v200
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
127.0.0.1:6379> get k1
"v100"
127.0.0.1:6379> set k1 v1100
OK
127.0.0.1:6379> get k1
"v1100"
127.0.0.1:6379> append k1 bac
(integer) 8
127.0.0.1:6379> get k1
"v1100bac"
127.0.0.1:6379> strlen k1
(integer) 8
127.0.0.1:6379> setnx k1 v300
(integer) 0
127.0.0.1:6379> setnx k3 v300
(integer) 1
127.0.0.1:6379> set k4 500
OK
127.0.0.1:6379> incr k4
(integer) 501
127.0.0.1:6379> get k4
"501"
127.0.0.1:6379> decr k4
(integer) 500
127.0.0.1:6379> incrby k4 10
(integer) 510
127.0.0.1:6379> decrby k4 20
(integer) 490


Redis的incr是原子性操作,java中不是原子性操作



其他命令:


  • 设置多个键值对:mset k1 v1 k2 v2...


  • 获取多个value:mget k1 k2 ...


  • msetnx k1 v1 k2 v2 k3 v3:原子操作,要么全部成功,要么全部失败


  • getrange key start_index end_index:get范围内的值,索引从0开始


  • setrange key startindex val:将startindex位置上的值用val替代


  • setex key time value:设置过期时间,同时设置值


  • getset key value:返回旧值,同时设置新值


127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
//msetnx要么全部成功,要么全部失败
127.0.0.1:6379> msetnx k11 v11 k12 v12 k1 v11
(integer) 0
127.0.0.1:6379> msetnx k11 v11 k12 v12 k13 v13
(integer) 1
127.0.0.1:6379> keys *
1) "k1"
2) "k3"
3) "k12"
4) "k13"
5) "k2"
6) "k11"
127.0.0.1:6379> set name lucymary
OK
127.0.0.1:6379> getrange name 0 3
"lucy"
127.0.0.1:6379> setrange name 3 abc
(integer) 8
127.0.0.1:6379> get name
"lucabcry"
//设置定时器    
127.0.0.1:6379> setex age 10 value30
OK
127.0.0.1:6379> ttl age
(integer) 4
127.0.0.1:6379> ttl age
(integer) -2
//给key设置新值    
127.0.0.1:6379> getset name jack
"lucabcry"
127.0.0.1:6379> get name
"jack"


string的数据结构是简单的动态字符串



3. list


单键多值


多个value存储为list,底层为双向链表


常用命令:


  • lpush/rpush key value value...:从左或者右插入一个或者多个值(头插与尾插)


  • lpop/rpop key :从左或者右吐出一个或者多个值(值在键在,值都没,键都没)


  • rpoplpush key1 key2: 从key1列表右边吐出一个值,插入到key2的左边


  • lrange key start stop 按照索引下标获取元素(从左到右)


  • lrange key 0 -1: 获取所有值


  • lindex key index 按照索引下标获得元素


  • llen key 获取列表长度


  • linsert key before/after value newvalue 在value的前面插入一个新值


  • lrem key n value 从左边删除n个value值


  • lset key index value 在列表key中的下标index中修改值value


127.0.0.1:6379> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
127.0.0.1:6379> rpush k2 v1 v2 v3
(integer) 3
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> lpop k1
"v3"


127.0.0.1:6379> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> rpush k2 v11 v12 v13
(integer) 3
127.0.0.1:6379> rpoplpush k1 k2
"v1"
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "v11"
3) "v12"
4) "v13"
//索引取值
127.0.0.1:6379> lindex k2
(error) ERR wrong number of arguments for 'lindex' command
127.0.0.1:6379> lindex k2 0
"v1"
127.0.0.1:6379> lindex k2 2
"v12"
//获取长度    
127.0.0.1:6379> llen k2
(integer) 4
//指定位置插入值    
127.0.0.1:6379> linsert k2 before "v11" "newv11"
(integer) 5
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newv11"
3) "v11"
4) "v12"
5) "v13"
127.0.0.1:6379> linsert k2 before "v12" "newv11"
(integer) 6
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newv11"
3) "v11"
4) "newv11"
5) "v12"
6) "v13"
127.0.0.1:6379> linsert k2 before "v13" "newv11"
(integer) 7
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newv11"
3) "v11"
4) "newv11"
5) "v12"
6) "newv11"
7) "v13"
//删除指定值,且可以指定个数    
127.0.0.1:6379> lrem k2 2 "newv11"
(integer) 2
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "v11"
3) "v12"
4) "newv11"
5) "v13"
//指定位置替换值    
127.0.0.1:6379> lset k2 1 newnew
OK
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newnew"
3) "v12"
4) "newv11"
5) "v13"



4. set


底层是字典,通过哈希表实现


自动排重且为无序的


常用命令:


  • sadd key value value... 将一个或者多个member元素加入集合key中,已经存在的member元素被忽略


  • smembers key 取出该集合的所有值


  • sismember key value 判断该集合key是否含有改值


  • scard key 返回该集合的元素个数


  • srem key value value 删除集合中的某个元素


  • spop key 随机从集合中取出一个元素


  • srandmember key n 随即从该集合中取出n个值,不会从集合中删除


  • smove <一个集合a><一个集合b>value 将一个集合a的某个value移动到另一个集合b


  • sinter key1 key2 返回两个集合的交集元素


  • sunion key1 key2 返回两个集合的并集元素


  • sdiff key1 key2 返回两个集合的差集元素(key1有的,key2没有)


127.0.0.1:6379> sadd k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> smembers k1
1) "v2"
2) "v3"
3) "v1"
//判断set中是否有值
127.0.0.1:6379> sismember k1 v1
(integer) 1
127.0.0.1:6379> sismember k1 v4
(integer) 0
//返回集合中元素个数
127.0.0.1:6379> scard k1
(integer) 3
//删除元素
127.0.0.1:6379> srem k1 v1 v2
(integer) 2
127.0.0.1:6379> smembers k1
1) "v3"


127.0.0.1:6379> sadd k2 v1 v2 v3 v4
(integer) 4
//随机删除元素
127.0.0.1:6379> spop k2
"v1"
127.0.0.1:6379> spop k2
"v4"
127.0.0.1:6379> spop k2
"v3"


127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd k2 v1 v2 v3 v4
(integer) 4
127.0.0.1:6379> srandmember k2 2    //随机取值
1) "v2"
2) "v3"
127.0.0.1:6379> srandmember k2 2
1) "v1"
2) "v3"


127.0.0.1:6379> sadd k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> sadd k2 v3 v4 v5
(integer) 3
//将k1中的v3移入到k2中    
127.0.0.1:6379> smove k1 k2 v3
(integer) 1
127.0.0.1:6379> smembers k1
1) "v2"
2) "v1"
127.0.0.1:6379> smembers k2
1) "v5"
2) "v3"
3) "v4"
127.0.0.1:6379>  sadd k3 v3 v4 v5 v7
(integer) 4
127.0.0.1:6379> sinter k2 k3   //交集
1) "v5"
2) "v3"
3) "v4"
127.0.0.1:6379> sunion k2 k3  //并集
1) "v7"
2) "v3"
3) "v4"
4) "v5"
127.0.0.1:6379> sdiff k3 k2  //差集
1) "v7"


5. hash


hash是键值对集合,是一个string类型的field和value的映射表,hash特别适合用于存储对象。


常用命令:


  • hset key field value: 给key集合中的filed键赋值value


  • hget key1 field :集合field取出value


  • hmset key1 field1 value1 field2 value2 :批量设置hash的值


  • hexists key1 field: 查看哈希表key中,给定域field是否存在


  • hkeys key :列出该hash集合的所有field


  • hvals key :列出该hash集合的所有value


  • hincrby key field increment: 为哈希表key中的域field的值加上增量1 -1


  • hsetnx key field value :将哈希表key中的域field的值设置为value,当且仅当域field不存在



127.0.0.1:6379> hset user:1001 id 1   //插入数据:键 域 值
(integer) 1
127.0.0.1:6379> hset user:1001 name zhangsan
(integer) 1
127.0.0.1:6379> hget user:1001 id
"1"
127.0.0.1:6379> hget user:1001 name
"zhangsan"
//一次性插入    
127.0.0.1:6379> hmset user:1002 id 2 name lisi age 30
OK
//判断是否存在域    
127.0.0.1:6379> hexists user:1002 id
(integer) 1
127.0.0.1:6379> hexists user:1002 gender
(integer) 0
//获取所有域    
127.0.0.1:6379> hkeys user:1002
1) "id"
2) "name"
3) "age"
//获取所有值    
127.0.0.1:6379> hvals user:1002
1) "2"
2) "lisi"
3) "30"
127.0.0.1:6379> hincrby user:1002 age 2
(integer) 32
127.0.0.1:6379> hsetnx user:1002 age 40
(integer) 0
127.0.0.1:6379> hsetnx user:1002 gender 1
(integer) 1


hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。


6. zset


有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合


常用命令:


  • zadd key score1 value1 score2 value2 :将一个或多个member元素及其score值加入到有序key中


  • zrange key start stop (withscores) :返回有序集key,下标在start与stop之间的元素,带withscores,可以让分数一起和值返回到结果集。


  • zrangebyscore key min max(withscores): 返回有序集key,所有score值介于min和max之间(包括等于min或max)的成员。有序集成员按score的值递增次序排列


  • zrevrangebyscore key max min (withscores):同上,改为从大到小排列


  • zincrby key increment value :为元素的score加上增量


  • zrem key value :删除该集合下,指定值的元素


  • zcount key min max :统计该集合,分数区间内的元素个数


  • zrank key value :返回该值在集合中的排名,从0开始


127.0.0.1:6379> zadd topn 200 java 300 c++ 400 mysql 500 php
(integer) 4
127.0.0.1:6379> zrange topn 0 -1
1) "java"
2) "c++"
3) "mysql"
4) "php"
127.0.0.1:6379> zrange topn 0 -1 withscores
1) "java"
2) "200"
3) "c++"
4) "300"
5) "mysql"
6) "400"
7) "php"
8) "500"
127.0.0.1:6379> zrangebyscore topn 300 500
1) "c++"
2) "mysql"
3) "php"
127.0.0.1:6379> zrangebyscore topn 300 500 withscores
1) "c++"
2) "300"
3) "mysql"
4) "400"
5) "php"
6) "500"
127.0.0.1:6379> zrevrangebyscore topn 500 300
1) "php"
2) "mysql"
3) "c++"
127.0.0.1:6379> zincrby topn 50 java
"250"
127.0.0.1:6379> zcount topn 200 300
(integer) 2
127.0.0.1:6379> zrank topn java
(integer) 0
127.0.0.1:6379> zrank topn mysql
(integer) 2
127.0.0.1:6379> zrange topn 0 -1 withscores
1) "java"
2) "250"
3) "c++"
4) "300"
5) "mysql"
6) "400"
7) "php"
8) "500"


zset底层使用了两个数据结构:


  1. hash,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。


  1. 跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。


4. 配置文件


先打开配置文件:sudo gedit /etc/redis.conf



//1. 注释掉这一行
#bind 127.0.0.1 -::1
//2. 保护模式改成no
protected-mode no
//3. 后台启动改成yes
daemonize yes




添加密码:


5. 发布和订阅


什么是发布订阅:


发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。





相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
8天前
|
NoSQL 关系型数据库 MySQL
redis 入门01
redis 入门01
17 0
|
8天前
|
缓存 NoSQL Java
【Redis系列笔记】Redis入门
本文介绍了Redis常用命令,以及SpringBoot集成Spring Data Redis和Spring Cache。Spring Data Redis 提供了对 Redis 的操作方法,而 Spring Cache 则提供了基于注解的缓存功能,可以方便地将方法的返回值缓存到 Redis 中,以提高性能和减少对数据源的访问次数。这样的集成可以帮助开发者更便捷地利用 Redis 来管理应用程序的数据和缓存。
102 4
|
8天前
|
存储 缓存 NoSQL
Redis入门到通关之Redis内存淘汰(内存过期)策略
Redis入门到通关之Redis内存淘汰(内存过期)策略
38 3
|
8天前
|
存储 NoSQL Linux
Redis入门到通关之多路复用详解
Redis入门到通关之多路复用详解
26 1
|
8天前
|
存储 NoSQL Linux
Redis入门到通关之Redis5种网络模型详解
Redis入门到通关之Redis5种网络模型详解
36 1
|
8天前
|
NoSQL Ubuntu 关系型数据库
Redis入门到通关之Redis网络模型-用户空间和内核态空间
Redis入门到通关之Redis网络模型-用户空间和内核态空间
23 1
|
8天前
|
存储 NoSQL 算法
Redis入门到通关之Redis数据结构-Hash篇
Redis入门到通关之Redis数据结构-Hash篇
29 1
|
8天前
|
存储 NoSQL Redis
Redis入门到通关之Redis数据结构-Set篇
Redis入门到通关之Redis数据结构-Set篇
33 1
|
8天前
|
存储 NoSQL Redis
Redis入门到通关之Redis数据结构-ZSet篇
Redis入门到通关之Redis数据结构-ZSet篇
37 1
|
8天前
|
存储 NoSQL Redis
Redis入门到通关之Redis数据结构-List篇
Redis入门到通关之Redis数据结构-List篇
36 1