Redis学习记录(Linux环境)
概述
- redis应用场景
- 五大数据类型
- redis事务处理
- redis监控(watch)
- redis客户端—Jedis
- redis持久化(rdb,aof)
- redis与python交互案例(widows)
Nosql概略
Redis
-
概述:远程字典服务。提供多种语言的API,
-
用处:
- 内存存储、持久化,内存中是断电即失(持久化重要,rdb,aof)
- 效率高,高速缓存
- 发布订阅系统
- 地图信息分析
- 计时器、计数器
-
特性
- 多样的数据类型
- 持久化
- 集群
- 事务
-
学习
官网:https://redis.io/
-
安装
- 官网下载
-
解压
[root@hadoop100 soft]# ll 总用量 4 drwxr-xr-x. 9 root root 220 4月 11 16:32 apache-tomcat-8.5.78 drwxr-xr-x. 8 10143 10143 273 12月 16 03:30 jdk1.8.0_321 drwxr-xr-x. 10 root root 184 4月 12 12:57 mysql drwxrwxr-x. 6 root root 4096 10月 4 2021 redis-5.0.14 drwxr-xr-x. 2 root root 159 4月 14 18:44 yumFile [root@hadoop100 soft]# cd redis-5.0.14/ [root@hadoop100 redis-5.0.14]# ll 总用量 284 -rw-rw-r--. 1 root root 127554 10月 4 2021 00-RELEASENOTES -rw-rw-r--. 1 root root 53 10月 4 2021 BUGS -rw-rw-r--. 1 root root 2381 10月 4 2021 CONTRIBUTING -rw-rw-r--. 1 root root 1487 10月 4 2021 COPYING drwxrwxr-x. 6 root root 124 10月 4 2021 deps -rw-rw-r--. 1 root root 11 10月 4 2021 INSTALL -rw-rw-r--. 1 root root 151 10月 4 2021 Makefile -rw-rw-r--. 1 root root 6888 10月 4 2021 MANIFESTO -rw-rw-r--. 1 root root 20555 10月 4 2021 README.md -rw-rw-r--. 1 root root 63088 10月 4 2021 redis.conf -rwxrwxr-x. 1 root root 275 10月 4 2021 runtest -rwxrwxr-x. 1 root root 280 10月 4 2021 runtest-cluster -rwxrwxr-x. 1 root root 373 10月 4 2021 runtest-moduleapi -rwxrwxr-x. 1 root root 281 10月 4 2021 runtest-sentinel -rw-rw-r--. 1 root root 9710 10月 4 2021 sentinel.conf drwxrwxr-x. 3 root root 4096 10月 4 2021 src drwxrwxr-x. 11 root root 182 10月 4 2021 tests drwxrwxr-x. 8 root root 4096 10月 4 2021 utils
-
安装gcc-c++(环境)
yum install gcc-c++
执行make
查看:安装完成
默认安装路径:/usr/local/bin
复制配置文件
修改配置文件
启动redis服务(指定配置文件启动)
[root@hadoop100 bin]# redis-server rconfig/redis.conf 9885:C 27 Apr 2022 16:39:36.013 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 9885:C 27 Apr 2022 16:39:36.013 # Redis version=5.0.14, bits=64, commit=00000000, modified=0, pid=9885, just started 9885:C 27 Apr 2022 16:39:36.013 # Configuration loaded
连接成功
[root@hadoop100 bin]# redis-cli -p 6379 127.0.0.1:6379>
测试成功
127.0.0.1:6379> ping PONG 127.0.0.1:6379> set name qiyou OK 127.0.0.1:6379> get name "qiyou" 127.0.0.1:6379> keys * 1) "name" 127.0.0.1:6379>
查看redis进程
Last login: Wed Apr 27 16:22:51 2022 from 192.168.126.1 [root@hadoop100 ~]# ps -ef|grep redis root 9886 1 0 16:39 ? 00:00:00 redis-server 127.0.0.1:6379 root 10103 1872 0 16:40 pts/0 00:00:00 redis-cli -p 6379 root 11254 11174 0 16:45 pts/1 00:00:00 grep --color=auto redis
关闭服务,退出连接
127.0.0.1:6379> shutdown not connected> exit
-
redis-benchmark——压力测试工具
实战测试
#100个并发连接,100000请求 [root@hadoop100 bin]# ll 总用量 32860 -rw-r--r--. 1 root root 110 4月 27 16:46 dump.rdb drwxr-xr-x. 2 root root 24 4月 27 16:38 rconfig -rwxr-xr-x. 1 root root 4367064 4月 27 16:31 redis-benchmark -rwxr-xr-x. 1 root root 8153064 4月 27 16:31 redis-check-aof -rwxr-xr-x. 1 root root 8153064 4月 27 16:31 redis-check-rdb -rwxr-xr-x. 1 root root 4808296 4月 27 16:31 redis-cli lrwxrwxrwx. 1 root root 12 4月 27 16:31 redis-sentinel -> redis-server -rwxr-xr-x. 1 root root 8153064 4月 27 16:31 redis-server [root@hadoop100 bin]# redis-benchmark -h localhost -p 6379 -c 100 -n 100000
16个数据库,默认使用第0个数据库,使用select进行切换
#切换数据库 127.0.0.1:6379> select 3 OK 127.0.0.1:6379[3]> #查看数据库大小 127.0.0.1:6379[3]> DBSIZE (integer) 0 127.0.0.1:6379[3]> set name qiyou01 OK 127.0.0.1:6379[3]> DBSIZE (integer) 1 127.0.0.1:6379[3]> #清除全部数据库 127.0.0.1:6379> keys * 1) "mylist" 2) "key:__rand_int__" 3) "name" 4) "counter:__rand_int__" 5) "myset:__rand_int__" 127.0.0.1:6379> flushdb OK 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379>
-
redis是单线程的
基于内存操作,瓶颈根据机器的内存和网络带宽,所以可以使用单线程。
- 误区1:高性能的服务器一定是多线程的
- 误区2:多线程(CPU上下文会切换,耗时)一定比单线程高(CPU>内存>硬盘)
核心:将所有数据放在内存,使用单线程效率高
五大数据类型
Redis可以用作数据库,缓存,消息中间件支持多种类型的数据结构。
Redis-Key
127.0.0.1:6379> set name qiyou01
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> set age 1
OK
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> EXISTS name
(integer) 1
#移除name
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> keys *
1) "age"
#设置10秒后过期
#可以设置单点登录
127.0.0.1:6379> set name qiyou01
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> get name
"qiyou01"
127.0.0.1:6379> EXPIRE name 10
(integer) 1
#查看还剩几秒过期
127.0.0.1:6379> ttl name
(integer) 2
127.0.0.1:6379> ttl name
#-2:表示已经过期
(integer) -2
#查看当前key是什么类型
127.0.0.1:6379> type age
string
127.0.0.1:6379>
String
#在已有的键名的内容后面追加字符串
127.0.0.1:6379> set key1 v1
OK
127.0.0.1:6379> get key1
"v1"
#如多当前key不存在,则相当于set一个key
127.0.0.1:6379> APPEND key1 "helllo"
(integer) 8
127.0.0.1:6379> get key1
"v1helllo"
#截取字符串长度
127.0.0.1:6379> STRLEN key1
(integer) 8
===============================================
#自增自减,步长加减
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> decr views
(integer) 1
127.0.0.1:6379>
#加10
127.0.0.1:6379> INCRBY views 10
(integer) 11
127.0.0.1:6379>
#减5
127.0.0.1:6379> DECRBY views 5
(integer) 6
127.0.0.1:6379>
#截取字符串范围
127.0.0.1:6379> set key1 abcde
OK
127.0.0.1:6379> get key1
"abcde"
127.0.0.1:6379> GETRANGE key1 0 3
"abcd"
#替换指定位置开始的字符串
127.0.0.1:6379> SETRANGE key1 1 ss
(integer) 5
127.0.0.1:6379> get key1
"assde"
===========================================
#seten 设置过期时间
127.0.0.1:6379> setex key1 30 "abcdr"
OK
127.0.0.1:6379> ttl key1
(integer) 23
127.0.0.1:6379> ttl key1
(integer) -2
#setnx 不存在在设置(在分布式锁中常常使用)
127.0.0.1:6379> setnx mykey "redis"
#mykey不存在,创建成功
(integer) 1
127.0.0.1:6379> keys *
1) "mykey"
#mykey存在,创建失败
127.0.0.1:6379> setnx mykey "mongoDB"
(integer) 0
#mset:创建多个key
#mget:查看多个key
String类似的使用场景:value除了是字符串还是数字
- 计数器
- 统计多单位的数量
- uid:XXXXXXX:follow 0 incr/decr
- 粉丝数
- 对象缓存存储
List
基本的数据类型,列表
LPUSH
LRANGE
RPUSH
PRANGE
Set
值无序不能重复
#添加值
127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "qiyou"
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
#查询值
127.0.0.1:6379> SMEMBERS myset
1) "world"
2) "qiyou"
3) "hello"
#查询指定值
127.0.0.1:6379> SISMEMBER myset hello
(integer) 1
127.0.0.1:6379> SISMEMBER myset qiqi
(integer) 0
==============================================
#获取set集合中的内容元素个数
127.0.0.1:6379> scard myset
(integer) 3
#移除某个值
127.0.0.1:6379> srem myset hello
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "world"
2) "qiyou"
#随机抽取一个元素
127.0.0.1:6379> SRANDMEMBER myset
"qiyou"
127.0.0.1:6379> SRANDMEMBER myset
"world"
#随机删除set集合中的元素
127.0.0.1:6379> spop myset
"qiyou"
127.0.0.1:6379> SMEMBERS myset
1) "world"
#移动指定元素
127.0.0.1:6379> smove myset myset2 "world"
(integer) 1
127.0.0.1:6379> SMEMBERS myset
(empty list or set)
127.0.0.1:6379> SMEMBERS myset2
1) "world"
====================================================
#交集:b站、微博共同关注
127.0.0.1:6379> sadd key1 a
(integer) 1
127.0.0.1:6379> sadd key1 b
(integer) 1
127.0.0.1:6379> sadd key1 c
(integer) 1
127.0.0.1:6379> sadd key2 c
(integer) 1
127.0.0.1:6379> sadd key2 d
(integer) 1
127.0.0.1:6379> sadd key2 e
(integer) 1
#key1中与key2不同的元素
127.0.0.1:6379> SDIFF key1 key2
1) "b"
2) "a"
#查看key1与key2中不同的元素
127.0.0.1:6379> SINTER key1 key2
1) "c"
#并集(无序)
127.0.0.1:6379> SUNION key1 key2
1) "c"
2) "d"
3) "b"
4) "a"
5) "e"
Hash
Map
#存值、取值
127.0.0.1:6379> hset myhash file1 qiyou
(integer) 1
127.0.0.1:6379> hget myhash file1
"qiyou"
#存取多个值(若存在则覆盖)
127.0.0.1:6379> hmset myhash file1 hello file2 world
OK
127.0.0.1:6379> hmget myhash file1 file2
1) "hello"
2) "world"
#取所有值
127.0.0.1:6379> hgetall myhash
1) "file1"
2) "hello"
3) "file2"
4) "world"
#删除值
127.0.0.1:6379> hdel myhash file1
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "file2"
2) "world"
#只获取key
#只获取value127.0.0.1:6379> hkeys myhash
127.0.0.1:6379> hkeys myhash
1) "file2"
127.0.0.1:6379> hvals myhash
1) "world"
hash可以做变更的数据:用户信息的保存,user name age,hash适合对象的存储,String适合子字符串的存储;
比较String和Hash存储,Hash多用作经常变更的数据,对象(用户信息等等)缓存存储较多,String多用作需要大量访问的字段。
Zset
有序集合,在set的基础上加了一个值,set k1 v1 zset k1 score1 v1
#排序
127.0.0.1:6379> zadd salary 2500 one
(integer) 1
127.0.0.1:6379> zadd salary 5000 two
(integer) 1
127.0.0.1:6379> zadd salary 500 three
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf
1) "three"
2) "one"
3) "two"
三大特殊类型
geospatial地理位置
Hyperloglog
Bitmap
Redis事务
Redis单条命令保持原子性,但是事务不保证原子性!
Redis事务本质:一组命令的集合,一个事务的所有命令都会序列化,执行过程中,会按照顺序执行!一次性,顺序性,排他性
- Redis没有隔离级别的概念
- 所有的命令在事务中没有直接被执行,只有发起执行命令的适合==时候才会执行
redis的事务
- 开启事务:muiti
- 命令入队:…
- 执行事务:exec
- DISCARD:放弃事务
- 编译型异常:命令错误,代码有问题不会执行事务中的所有命令,执行事务报错
- 运行时异常:事务队列存在语法错误(如对第一条字符串数据进行了自加命令),其他命令可以执行,错误命令抛出异常。
#开启事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) OK
#放弃事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> get k4
(nil)
监控:Watch
-
悲观锁
- 很悲观,什么时候都会出问题,无论做什么都会加锁
-
乐观锁
- 认为什么时候都不会出问题,不会上锁,更新数据的时候判断在此期间是否修改过这个数据
- 获取version
- 更新的时候比较version
测监视测试:
#正常执行成功 #监视money对象,事务正常结束 127.0.0.1:6379> set money 100 OK 127.0.0.1:6379> set out 0 OK 127.0.0.1:6379> watch money OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> DECRBY money 20 QUEUED 127.0.0.1:6379> INCRBY out 20 QUEUED #监视成功,事务执行成功 127.0.0.1:6379> exec 1) (integer) 80 2) (integer) 20
#执行失败 #测试多线程修改值,使用watch当作redis的乐观锁操作 #一个线程修改存款到1000 127.0.0.1:6379> get money "80" 127.0.0.1:6379> set money 1000 OK 127.0.0.1:6379> get money "1000" #另一个线程执行事务取钱,使用watch监控 127.0.0.1:6379> watch money OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> DECRBY money 10 QUEUED 127.0.0.1:6379> INCRBY out 10 QUEUED #执行事务失败,修改了值 127.0.0.1:6379> exec (nil)
#解决方法 #如果事务失败,先解锁 127.0.0.1:6379> unwatch OK #获取最新的值,再次监视 127.0.0.1:6379> watch money OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> DECRBY money 30 QUEUED 127.0.0.1:6379> INCRBY money 30 QUEUED #比对最新的值是否发生变化,没有变化可以执行成功,有则失败,如果失败,重新解锁 127.0.0.1:6379> exec 1) (integer) 970 2) (integer) 1000
Jedis
导入Jedis包:Maven Repository: Search/Browse/Explore (mvnrepository.com)
测试
-
导入对应依赖
<!--导入jsdis的包--> <dependencies> <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>4.1.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.77</version> </dependency> </dependencies>
-
编码测试
-
出现的错误
- 实践通过Jedis操作Redis时,导入Jedis依赖出错,project language level版本不对,改成8之后syntax成功。
- 新建jedis对象时导入Redis包不成功,重启idea后等待更新成功。
- Java测试连接Linux下的Redis时报错:Failed to connect to any host resolved for DNS name,需要修改redis配置文件:将bind那行注释掉,并将protected-mode改为no;关闭防火墙;设置安全组:
-
连接查看是否ping成功:返回PONG。
package com.course; import redis.clients.jedis.Jedis; public class TestPing { public static void main(String[] args) { //newJedis对象 Jedis jedis=new Jedis("127.0.0.1",6379); System.out.println(jedis.ping()); } }
-
Redis持久化操作
SECURITY 安全
设置Redis密码
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> config get requirpass
(empty list or set)
127.0.0.1:6379> config set requirepass "XXXXXXXX"
OK
127.0.0.1:6379> auth XXXXXXXX
OK
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "XXXXXXXX"
客户端限制
RDB
Redis单独创建(fork)一个子进程来进行持久化,数据写入临时文件,进程结束存入临时文件。
-
测试
删除dump.rdb,在连接redis执行数据操作后会自动生成rdb文件(持久化),退出Redi,重新登录,(rdb文件存在的话),get key仍然可以获取数据,若删除dump.rdb,则flush后生成的rdb会刷新,数值没有了。
-
触发机制
- save 的规则满足,自动触发rdb规则
- 执行flushall命令,触发rdb规则
- 退出redis也会生成rdb文件
-
恢复rdb文件
127.0.0.1:6379> config get dir 1) "dir" 2) "/usr/local/bin" #如果在这个目录下存在dump.rdb文件,启动就会自动恢复其中的数据
-
优点
- 适合大规模的数据恢复
- 对数据的完整性要求不高
-
缺点
- 需要一定的时间间隔
- 发生意外,最后一次修改的数据没有了
- fork进程的适合,会占用一定的空间
AOF
默认不开启,需要手动设置配置!将:appendonly改为yes就可以开启aof
-
重启服务
127.0.0.1:6379> shutdown not connected> exit [root@hadoop100 bin]# redis-server rconfig//redis.conf 26735:C 29 Apr 2022 19:55:59.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 26735:C 29 Apr 2022 19:55:59.480 # Redis version=5.0.14, bits=64, commit=00000000, modified=0, pid=26735, just started 26735:C 29 Apr 2022 19:55:59.480 # Configuration loaded [root@hadoop100 bin]# redis-cli -p 6379 127.0.0.1:6379> ping PONG
检查bin目录下是否生成aof文件
如果aof文件被破坏,Redis是启动不了的,用自动检测文件修复这个文件
-
修改数据
-
启动失败
[root@hadoop100 bin]# redis-server rconfig//redis.conf 27983:C 29 Apr 2022 20:02:20.587 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 27983:C 29 Apr 2022 20:02:20.587 # Redis version=5.0.14, bits=64, commit=00000000, modified=0, pid=27983, just started 27983:C 29 Apr 2022 20:02:20.587 # Configuration loaded
-
自动检测修复
[root@hadoop100 bin]# redis-check-aof --fix appendonly.aof 0x 4d: Expected \r\n, got: 6868 AOF analyzed: size=97, ok_up_to=52, diff=45 This will shrink the AOF from 97 bytes, with 45 bytes, to 52 bytes Continue? [y/N]: y Successfully truncated AOF
-
重启成功
[root@hadoop100 bin]# redis-cli -p 6379 127.0.0.1:6379> ping PONG
-
优点
- 每一次修改都同步,文件更加完成
- 每秒同步一次,可能丢失一秒数据
- 从不同步,效率最高
-
缺点
- 修复速度比rdb慢
- 运行效率慢
-
总结
【来源网友】
- RDB持久化方式能够在指定的时间间隔内对你的数据进行快照存储。
- AOF 持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,,AOF命令以Redis协议追加保存每次写的操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
- 只做缓存,如果只希望数据在服务器运行的时候存在,可以不使用任何持久化
- 同时开启两种持久化方式
- 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
- RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件,因为RDB更适合用于备份数据库( AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的Bug。
- 性能建议
- 因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一 次就够了,只保留 save 9001 这条规则。
- 如果Enable AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上,默认超过原大小100%大小重写可以改到适当的数值。
- 如果不Enable AOF,仅靠Master-Slave Repllcation实现高可用性也可以,能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave 同时挂掉,会丢失 十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个,例如微博。
demo测试(Windows)
在Windows测试连接redis与python进行交互
-
安装redis
-
下载安装地址:https://github.com/MicrosoftArchive/redis/releases
-
修改配置文件redis.windows-service.conf,在requirepass foobared下添加requirepass 123456设置redis密码
-
在服务中重启redis服务,即可在命令行测试并验证密码:
-
启动临时服务:redis-server.exe redis.windows.conf,窗口关闭,服务就关闭
-
自定义Windows服务安装:redis-server.exe --service-install redis.windows.conf --service-name redisserver1 --loglevel verbose
-
命令
#安装服务:redis-server.exe --service-install redis.windows.conf --service-name redisserver1 --loglevel verbose #启动服务:redis-server.exe --service-start --service-name redisserver1 (error) NOAUTH Authentication required. #启动出现认证错误,输入密码即可 127.0.0.1:6379> auth "123456" OK 127.0.0.1:6379> ping PONG #停止服务:redis-server.exe --service-stop --service-name redisserver1 #卸载服务:redis-server.exe --service-uninstall--service-name redisserver1
-
-
案例:
print("=====================redis数据库=====================") import redis # 连接数据库 r = redis.Redis(host='127.0.0.1', port=6379, db=0) # 使用连接池连接数据库。这样就可以实现多个Redis实例共享一个连接池 pool = redis.ConnectionPool(host='127.0.0.1', port=6379) r = redis.Redis(connection_pool=pool) # mset(*args, **kwargs) # 批量设置 # r.mset(name="xixi", age=18) r.mset({"name":'xiyangyang', "age":18}) #批量设置值 print(r.get("name")) print(r.get("age"))
-
控制台操作案例
# python3.6操作redis数据库。使用前请先确保redis服务已经打开 import redis redis.Redis(host='127.0.0.1', port=6379, db=0) r = pool = redis.ConnectionPool(host='127.0.0.1', port=6379) r = redis.Redis(connection_pool=pool) while True: print('1.增加学生信息') print('2.退出') result = int(input('请输入想要执行操作的序号:')) if result == 1: id = input("请输入增加的学生id:") name = input("请输入增加的学生姓名:") age = input("请输入增加的学生年龄:") r.mset({id: 'id+', name: '+name+', age: '+age'}) # 批量设置值 print(r.get("name")) print(r.get("age")) elif result == 2: print('已退出') quit()
python命令行运行后无数据,返回none
数据库可以查到信息
重启再次运行,报错:redis身份验证错误,需要身份验证
redis.exceptions.AuthenticationError:.Authentication required.
验证密码后,取消密码即可增删改查
#获取密码
config get requirepass
#修改密码
config set requirepass 765314
#取消密码
config set requirepass ''
添加信息成功