Redis基础

Redis是一个单进程模型的NoSQL数据库,支持KV键值、文档型、列存储和图关系数据库。它遵循CAP理论,更偏向于CP。Redis提供了String、Hash、List、Set和Sorted Set等五大数据类型,其中List底层基于linkedlist实现。持久化策略包括RDB(快照)和AOF(追加日志),RDB在指定时间间隔内将内存数据快照写入磁盘,AOF记录所有写操作,支持重写机制以减小文件体积。此外,Redis还支持事务、消息发布订阅和主从复制功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis

NoSQL

Not Only SQL:不需要固定的模式储存,可以横向扩展,泛指非关系型数据库。

BSon可以画出非关系型数据模型,binary Json。例如下单:本来关系型数据库一个id要查订单表,收货地址表等等表,而非关系型数据库可以直接一个id查出所有信息(放入json串中)

NoSQL数据库的四大分类

  • KV键值:redis tier等
  • 文档型数据库:bson格式较多。MongoDB是一个基于分布式文件存储的数据库,是非关系型数据库中最像关系型数据库的。
  • 列存储数据库:列存储数据库
  • 图关系数据库:Neo4J

四者对比:

CAP 和 BASE

传统 ACID

  • Atomicity 原子性
  • Consistency:一致性
  • Isolation:隔离性
  • Duration:持久性

CAP

  • Consistency:强一致性
  • Availablity:可用性
  • Partition tolerance:分区容错性

P是必须要实现的。

CA:RDBMS

AP:大部分网站架构的选择

CP:Redis, Mongodb

BASE

  • Basically Avaliable:基本可用
  • Soft state:软状态
  • Eventually consistent:最终一致性

分布式 集群

分布式:不同机器上部署不同模块,通过rpc rmi调用

集群:不同机器上部署相同模块

Redis

Remote Dictionary Server(远程字典服务器)Redis是单进程模型来处理客户端请求,通过对 epoll 函数的包装来做到的。

默认16个库,0-15。DBsize 能获取当前 key 的个数。keys * 能获取所有 key,类似 select * 。可以用占位符。FLUSHALL删除所有16个库,FLUSHDB删除当前库。

key 关键字

move k3 2 //把k3搬运到2号库
exists a //判断a是否存在 存在返回 1
ttl a //判断a还能活多久 time to live -1表示永久
expire a 18 //设定key过期时间,过期后,移除内存系统, 返回值 -2
del a  //删除 a
type a //a 是什么类型
INCR a // a++
append a // 追加写
getrange a 0 -1 //获取全部
setex a 10 value // 设置过期
setnx a value // 加入不存在 则写入

Redis 五大数据类型

String

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"

Hash

127.0.0.1:6379> hset user a b
(integer) 1
127.0.0.1:6379> hget user a
"b"
127.0.0.1:6379> hmset person name hello age 12
OK
127.0.0.1:6379> hgetall person
1) "name"
2) "hello"
3) "age"
4) "12"
127.0.0.1:6379> hlen person
(integer) 2

List

底部是个 linkedlist

127.0.0.1:6379> LPUSH list 0 1 2 3 4 5  //头插法
(integer) 6
127.0.0.1:6379> LRANGE list  0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
6) "0"
127.0.0.1:6379> lpop list
"5"
127.0.0.1:6379> lpop list
"4"
127.0.0.1:6379> rpop list
"0"
127.0.0.1:6379>

Set

无序,无重复

127.0.0.1:6379> sadd set 1 1 2 2 3 4 4
(integer) 4
127.0.0.1:6379> scard set // 获取set中元素个数
(integer) 4
127.0.0.1:6379> srem set 1 // 删除set中元素
(integer) 1
127.0.0.1:6379> smembers set
1) "2"
2) "3"
3) "4"
127.0.0.1:6379> spop set
"4"
差集:sdiff
交集:sinter
并集:sunion
127.0.0.1:6379> sadd set1 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd set2 1 2 4 5 6
(integer) 5
127.0.0.1:6379> sdiff set1 set2
1) "3"
127.0.0.1:6379> sinter set1 set2
1) "1"
2) "2"
3) "4"
4) "5"
127.0.0.1:6379> sunion set1 set2
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"

ZSet(Sorted set)

每个元素前面加了一个double类型的分数,zset成员唯一,分数可以重复。

127.0.0.1:6379> zadd zset 80 v1 39 v2 44 v3 99 v4
(integer) 4
127.0.0.1:6379> zrange 0 -1
1) "v2"
2) "v3"
3) "v1"
4) "v4"
127.0.0.1:6379> zrangebyscore zset 40 60
1) "v3"
127.0.0.1:6379> zrem zset v4
(integer) 1
127.0.0.1:6379> zrange zset 0 -1
1) "v2"
2) "v3"
3) "v1"
127.0.0.1:6379> zcard zset
(integer) 3
127.0.0.1:6379> zcount zset 20 60
(integer) 2
127.0.0.1:6379> zscore zset v3
"44"

配置文件

general

include :可以引入别的配置

pid pid :当以守护进程启动后,会把pid写入 pid文件中

tcp-backlog :tcp连接队列

timeout:0 一直保持连接

tcp-keepalive :tcp存活时间

loglevel:日志级别

logfile:日志文件地址

databases:数据库个数

syslog-enabled:开启系统日志

snapshot

详见 RDB 和 AOF

other

SECURITY 可以设置密码

127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""

maxclient: 最大客户端

maxmemory:最大内存

maxmemory-policy volatile-lru:LRU算法,移除过期缓存,FIFO先进先出,默认是noeviction,永不过期

持久化

rdb

Redis DataBase:指定时间内把内存中的数据集快照写入磁盘中,Snapshot快照,恢复的时候把快照文件直接读到内存中。Redis会单独创建(fork:复制一个和当前进程一样的进程,所有数据都一样,但是是个全新的进程,并作为原来进程的子进程)一个子进程来进行持久化,先把数据写入到临时文件,待持久化过程结束了,在用这个临时文件替换上次持久化好的文件。整个过程中,主进程不进行任何IO操作。如果大规模恢复数据比AOF更好,缺点是持久化后的数据可能会丢失。保存为 dump.rdb。FLUSHALL会保存一份dump文件,但是里面是空的。

配置文件:

save <seconds> <changes>
save 60 10000
save 900 1
save 300 10
# after 900 sec(15 min) if 1 key changed
# after 300 sec(5 min) if 10 key changed
# after 60 sec(1 min) if 10000 key changed

stop-writes-on-bgsave-error yes:出现出错就停止写入
rdbcompression yes:使用LZF算法进行压缩,需要占用额外cpu
rdbchecksum:存储快照后,可以让redis使用CRC64来数据校验,增加10%性能损耗

备份rdb的机器和主机不同,主机和备机是不同机器。

save直接调用rdbSave,阻塞Redis主进程,bgsave则是异步保存rdb。子进程创建后,父子进程共享数据段,父进程继续提供读写服务,此时如果父进程对数据进行修改。

这个时候就会使用操作系统的 COW (Copy On Write)机制来进行数据段页面的分离。数据段是由很多操作系统的页面组合而成,当父进程对其中一个页面的数据进行修改时,会将被共享的页面复制一份分离出来,然后对这个复制的页面进行修改。这时子进程相应的页面是没有变化的,还是进程产生时那一瞬间的数据。子进程因为数据没有变化,接下来就可以非常安心的遍历数据了进行序列化写磁盘了。

aof

Append Only File:以日志形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只追加写,Redis启动初期会读取该文件重新构建数据。

aof和rdb可以共存,会找aof,如果aof有问题,可以使用 reids-check-aof --fix xxx.aof 来修复aof文件。同理还有redis-check-rdb。

aof追加写,会导致文件越来越大,新增了重写机制,当aof大于一定大小的时候,redis会启动aof文件内容压缩,如果只保留可以恢复数据的最小指令集,可以使用命令 bgrewriteaof。

配置文件:

appendonly yes:开启aof
Appendfsync:Always 类似mysql,立马刷盘;默认Everysec:每秒;No:用不刷盘
No-appendfsync-on-rewrite:重写是否使用 Appendfsync,默认no即可
auto-aof-rewrite-percentage 100:当前AOF文件大小超过上一次重写的AOF
文件大小的百分之多少才会重写
auto-aof-rewrite-min-size 64mb :

事务

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 22
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get k2
"v2"

// 全体连坐
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> getset k3
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

// 冤头债主
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr k1
QUEUED
127.0.0.1:6379> set k2 22
QUEUED
127.0.0.1:6379> set k3 33
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> get k4
QUEUED
127.0.0.1:6379> exec
1) (error) ERR value is not an integer or out of range
2) OK
3) OK
4) OK
5) "v4"

这里的 incr k1 虽然出错,但是是放入队列了,所以 redis对事务的支持是部分支持。这里部分出错没有全部回滚。

// watch 监控,CAS
127.0.0.1:6379> set balance 100
OK
127.0.0.1:6379> set debt 0
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby balance 20
QUEUED
127.0.0.1:6379> incrby debt 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
// 这个时候另一个客户端修改了 balance 的钱
127.0.0.1:6379> watch balance
OK
如果另一个客户端修改了 balance 的值,执行事务后 会出现如下结果:
127.0.0.1:6379> exec
(nil)
一旦执行力 exec,之前加的监控锁都会被取消

消息发布订阅

// 推送消息
127.0.0.1:6379> publish new hello
(integer) 2

// 订阅消息
127.0.0.1:6379> psubscribe new *
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "new"
3) (integer) 1
1) "psubscribe"
2) "*"
3) (integer) 2

主从复制

主写,从读为主。配置的时候只要配置从库(slaveof)。使用命令 info replicaton 可以查看主从备份情况。从机连接上后会复制主机所有数据。从机写入值会报错:You cant write against a read only slave。主从备份的时候,从机不会变成主机,除非是 sentinel 集群。每次从和主机断开连接后,需要重新连接,要么写入从机配置文件中。使用 slaveof no one,这个时候他从从机变成了主机。

详见 Sentinel 和 Cluster 集群。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值