Redis 进阶学习笔记

Redis进阶学习笔记

阅读Redis.conf配置文件

# 61, 绑定的 IP , 一般注释掉该命令,这个吗,命令表示仅接受本机的(IP为本机)客户端连接,
bind 127.0.0.1 

# 80, yes: 保护模式 , 默认关闭, 允许外部客户端连接redis,no: 只能本机连接
protected-mode no

# 84, 端口号
port 6379

####### 整体配置 GENERAL #########

# 129, yes: 开启守护进程模式,重启机器, redis自启动,no: 机器重启需要手动启动redis
daemonize no

# 150, pid文件生成目录
pidfile /var/run/redis_6379.pid

# 158, 日志级别, 
# Redis 总共支持四个级别:debug、verbose、notice、warning
#  - debug:会打印生成大量信息,适用于开发/测试阶段
#  - verbose:包含很多不太有用的信息,但是不像debug级别那么混乱
#  - notice:适度冗长,适用于生产环境
#  - warning:仅记录非常重要、关键的警告消息
loglevel notice

# 163 , 打印日志目录
logfile ""

# 177, 16哥数据库
databases 16

########  快照  SNAPSHOTTING  ###########

# 快照 , 持久化操作,保存 redis数据库中的一个状态,用于恢复数据库,将redis持久化到 .rdb .aof文件中
#  - 900s,至少有 1 个key 发生了变化,才会持久化
#  - 300,至少有 10 个key 发生了变化,才会持久化
#  - 60s,至少有 10000 个key 发生了变化,才会持久化
save 900 1 
save 300 10
save 60 10000

# 219 , 持久化错误之后是否要工作
stop-writes-on-bgsave-error yes

# 225 , 是否压缩 rdb 文件
rdbcompression yes

# 234, 保存rdb文件是否要进行错误检查校验
rdbchecksum yes

# 236,rdb 文件的文件名
dbfilename dump.rdb

# 247, rdb 文件保存路径
dir ./

################## 安全设置 SECURITY ###################

# 480 ,设置密码 , 也可使用命令配置
requirepass 123456

##### 命令配置密码
	> config set requirepass 123
	> config get requirepass
	> auth 123 
##### end

################ LIMITS #############
# 512 , redis的最大链接数
maxclients 10000

# 537, redis配置的最大内存
maxmemory <bytes>

# 内存达到上限之后的处理方法
# - volatile lru	->  设置了过期时间的key进行lru移除
# - allkeys lru		->  删除所有
# - volatile random	->	删除即将过期的key
# - allkeys random	->	随机删除
# - volatile ttl	->	删除即将过期的
# - noeviction		->	永远不过期,直接报错
maxmemory-policy noeviction

############# AOF持久化 ###############
# 593,yes开启AOF持久化,默认是不开启的,默认使用RDB持久化,大部分情况下RDB完全够用
appendonly no

# 597 ,aof持计划文件名
appendfilename "appendonly.aof"

# 623 , 每次修改都会synch 消耗性能
#  - always , 每次修改都进行 aof持久化
#  - everysec , 每秒进行aof持久化
#  - no , 从不
appendfsync everysec


Redis持久化

Redis是内存数据库,断电即失去,只要是内存数据库就一定会有持久化操作

RDB(Redis DataBase)

在指定的时间 间隔内将内存中的数据集快照写入到磁盘中,Snapshot快照,恢复时将快照文件直接读到内存中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nE9UfBLd-1666273048107)(images/image-20211020090622824.png)]

RDB流程
  • 单独创建一个子进程,fork分支
  • 将内存内容写入临时RDB文件
  • 再用临时文件替换上次持久化完成的文件

​ 整个过程主进程不进行任何io操作,保证了性能,如果进行大规模数据恢复,RDBAOP都可以进行数据恢复,AOF数据恢复完整性不敏感,RDB更加高效,缺点时最后一次持久化后的数据可能丢失,默认使用的就是RDB,一般情况不需要修改这个配置

  • RDB保存的文件是dump.rdb
  • AOF保存的文件是appendonly.aof
dump.rdb文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V3TFJkTI-1666273048108)(images/image-20211020092100765.png)]

触发机制
  • save规则触发
  • 执行flushall命令
  • 关闭redis
如何恢复备份文件

​ 只要将rdb文件放在redis规定的目录,redis启动时会自动检查dump.rdb文件恢复数据,在生产环境中最好对dump.rdb文件进行备份

RDB优缺点

优点:

  • 父进程正常处理用户请求,fork分支一个子进程进行备份
  • 适合大规模的数据恢复,如果服务器宕机了,只要不删除RDB文件,重启以后还可以恢复数据**(最后一次的数据无法恢复,因为还没有生成新的rdb文件,就宕机了)**

缺点:

  • 需要一定的时间间隔,可以自行修改设置
  • 如果redis意外宕机,最后一次的修改数据会丢失
  • fork进程的时候,会占用一定的内存空间
AOF(Append Only File)
  • 将所执行的所有命令都记录下来,处读操作以外,恢复时重新执行一次,如果是大数据就需要写很久
  • aof默认是文件无限追加,大小会不断扩张
  • 在主从复制中,rdb是备用的,在从机上使用,aof一般不使用

AOF的本质就是保存 所有执行了命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gtnk4kn9-1666273048108)(images/image-20211020092943332.png)]

AOF流程
  • fork分支出子进程
  • 根据内存中的数据子进程创建临时aof文件
  • 父进程执行的命令存放在缓存中,并且写入原aof文件
  • 子进程完成新aof文件通知父进程
  • 父进程将缓存中的命令写入临时文件
  • 父进程用临时文件替换旧aof文件并重命名
  • 后面的命令都追加到新的aof文件中
开启AOF
appendonly no
#默认关闭appendonly 手动设置yes开启

appendfilename "appendonly.aof"
#默认名字

# appendfsync always
appendfsync everysec
# appendfsync no
#每次都进行修改
#每秒钟都进行修改 , 
#不进行修改

no-appendfsync-on-rewrite no
#是否进行重写

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
#percentage重写百分比
#重写时文件最小的体积


#一般保持默认,一般只需要开启

一般采用 appendfsync everysec 每秒钟触发一次,这样就算是宕机,也最多丢失1秒钟的数据。

测试开启aof
root@root:~# redis-cli -a 123456
127.0.0.1:6379> set name san
OK
127.0.0.1:6379> get name
"san"
127.0.0.1:6379> exit
root@root:~# cd /usr/local/redis/redis-3.2.10/
root@root:/usr/local/redis/redis-3.2.10# ls
00-RELEASENOTES  COPYING   Makefile    runtest           src
appendonly.aof   deps      MANIFESTO   runtest-cluster   tests
BUGS             dump.rdb  README.md   runtest-sentinel  utils
CONTRIBUTING     INSTALL   redis.conf  sentinel.conf

redis目录生成了appendonly.aof文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oxloy2o8-1666273048108)(images/image-20211020094035138.png)]

我们看到 AOF文件中存储的是我们的命令

破坏AOF文件以及修复aof文件

appendonly.aof文件中加入一串符号

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1YfKCekj-1666273048109)(images/image-20211020094229026.png)]

重启Redis,发现redis重启失败
使用redis-check-rdb修护aof文件
root@root:/usr/local/redis/redis-3.2.10# vim appendonly.aof
root@root:/usr/local/redis/redis-3.2.10# redis-check-aof --fix /usr/local/redis/redis-3.2.10/appendonly.aof
0x              37: Expected prefix 'b', got: '*'
AOF analyzed: size=90, ok_up_to=55, diff=35
This will shrink the AOF from 90 bytes, with 35 bytes, to 55 bytes
Continue? [y/N]: y
Successfully truncated AOF
root@root:/usr/local/redis/redis-3.2.10# cat appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$4
name
$3
san
root@root:/usr/local/redis/redis-3.2.10#

修复成功,删除了我添加的乱码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fti7JTOi-1666273048109)(images/image-20211020094943611.png)]

优缺点

优点:

  • 可设置文件修改每次都同步备份,文件完整性更好,但是消耗性能
  • 设置每秒同步一次可能会丢失一秒的数据
  • 从不同步效率最高

缺点

  • 对于数据文件,aof远远大于rdb,修复速度也比rdb
  • aofio操作,所以默认是aof
  • aof文件会无限扩大

所有我们一般不使用aof,而是使用rdb用作备份

Redis主从复制

一个Master有多个slave,将一台redis服务器数据,复制到其他的redis服务器,前者称为主节点(masterleader),后者称为从节点(slave、follower)数据是单向的,只能从主节点到从节点,Master以写为主,Slave以读为主

主从复制的特点

主从复制的特点

  • 数据是单向的,只能从主节点到从节点
  • Master以写为主,Slave以读为主
  • 主节点和从节点的数据都是一样的,主节点数据发生变化是,会同步所有从节点的数据。
  • 一个Master可以有多少Slave或没有从节点,一个从节点只能有一个主节点

默认情况下(非主从结构时),每台redis服务器都是主节点,一个Master可以有多少Slave或没有从节点,一个从节点只能有一个主节点

主从复制作用包括:
  • 数据冗余,实现了数据的热备份,是持久化之外的一种数据冗余方式
  • 故障恢复,主节点出现问题,从节点可以提供服务,实现快速的故障恢复,实际上是一种服务的冗余
  • 负载均衡,在主从复制的基础上,配合读写分离,主节点提供写服务,从节点提供读服务,写redis数据时连接主节点,读redis数据连接从节点,分担服务器负载,尤其在写少读多的场景下通过,多个从节点分担负载,可以提高redis性能
  • 高可用(集群)基石,哨兵、集群,能够实施的基础,主从复制时高可用的基础
不能只使用一台redis的原因:
  • 从结构上讲,单个redis服务器会发生单点故障,一台服务器需要处理所有请求,压力大
  • 从容量上讲,单个redis服务器内存容量有限,并且不能完全使用全部的内存,单台redis的最大内存不应该超过20g压力过大

通常的电商网站都是一次上传吗,无数次浏览,读多写少 ,主从复制,读写分离,80%的情况都在进行读操作,起码一主二从

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PjocTUcx-1666273048109)(images/image-20211020125023414.png)]

搭建Redis主从复制伪集群
cp三份redis.con文件到新的目录

cp三份redis.con文件到新的目录以80、81、81重命名

root@iZ2ze3e3cxev6ehgdt3qpdZ:~/redis# ls
redis80.conf  redis81.conf  redis82.conf  redis.conf
root@iZ2ze3e3cxev6ehgdt3qpdZ:~/redis#
修改三个配置文件的内容
# 1. 修改端口 6380、6381、6382
port 6380

# 2. 修改 pid 的文件名
pidfile /var/run/redis_6381.pid

# 3. 修改日志文件6380、6381、63812
logfile "6381.log"

# 4. 修改rdb文件名80、81、82
dbfilename dump81.rdb
分别启动三个redis
root@root:~/redis# redis-server redis80.conf
root@root:~/redis# redis-server redis81.conf
root@root:~/redis# redis-server redis82.conf

# 启动服务 redis-cli -p 6380 -a 123456
root@root:~/redis# 

6380

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gNGoE8Oa-1666273048112)(images/image-20211020151316622.png)]

6381

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UeHZJYSV-1666273048112)(images/image-20211020151341285.png)]

6382

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cxTXcSYQ-1666273048112)(images/image-20211020151331927.png)]

建立主从结构

主机master6380

从机slave63816382

slaveof 127.0.0.1 6379  # 设置 6380 为主机
info replication  # 查看 配置信息

从机设置主机,在6381、6382分别设置6380为主机

127.0.0.1:6381> slaveof 127.0.0.1 6379  # 设置 6380 为主机
OK
127.0.0.1:6381> info replication  # 查看 配置信息
# Replication
role:slave  # 表示自己为从机
master_host:127.0.0.1
master_port:6380
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1634715585
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6381>
127.0.0.1:6382> slaveof 127.0.0.1 6380  # 设置 6380 为主机
OK
127.0.0.1:6382> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1634715709
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6382>
查看的主机6380的配置信息
127.0.0.1:6380>  info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=43,lag=1
slave1:ip=127.0.0.1,port=6382,state=online,offset=43,lag=0
master_repl_offset:43
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:42
127.0.0.1:6380>

主从复制搭建成功

注意:

如果redis设置了密码,主从结构会失败,会出现主机找不到从机的问题

解决方法:

​ 从机在添加主机时,加上密码参数

主节用于写数据,从节点用于读数据
127.0.0.1:6381> set name san
(error) READONLY You can't write against a read only slave.
127.0.0.1:6381>

如果我们对从节点写数据,就会失败,只有主节点才可以写数据

######## master
127.0.0.1:6380> set name san
OK
127.0.0.1:6380>

######## slave
127.0.0.1:6381> get name
"san"
127.0.0.1:6381>
无哨兵的主从结构存在的问题
  • 主机宕机、从机依然还是从机,无法写只能读
  • 从机宕机,主机继续写入数据,从机恢复,能否get到恢复时段主机读取的值?
    • 没在redis.conf中设置的slave,读取不到崩溃时master set的数据
    • redis.conf中配置的slave,能读取到
    • 只要变为从机就会立马从主机中获取值

=====================================>

由此可见,如果主机一直宕机,从机一直都会是从机,将会导致系统不可用。如果主机恢复,主从配置没有写入到redis.conf文件中,将读取不到主机设置的值。

<=====================================

主从复制的原理
  • slave启动成功连接到master后会发送一个sync同步命令

  • master接到命令,启动后台的存盘进程,同时收集所接收到的用于修改数据集命令,后台执行完毕之后,master将传送整个数据文件到slave,并完成一次同步,成为增量复制

  • 只要重新连接master,**一次完全同步(全量复制)**将被自动执行,数据一定能在从机中看到

全量复制和增量复制
  • 全量复制,就是将主机的所有数据文件,全部同步。一般用在连接成功后,主机的一系列操作。
  • 增量复制,就是将同步对主机自己没有的数据。一般用在连接成功时,需要同步主机的所有数据。

主从复制

的两种结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m2leSEe6-1666273048113)(images/image-20211020165313050.png)]

  • 星型结构,所有从节点都直接连接在主节点上。

  • 链式结构,只有一个从节点直接到主节点,其他节点间接连接

    # 实现方式
    # 在 salve1:6380 设置主节点
    slaveof 127.0.0.1 3679
    # 在 salve2:6381 认 salve1 问主节点
        
    slaveof 127.0.0.1 3680
    

    这两种方法都一样,主机宕机,从节点都无法变成主节点

Master宕机解决方法
  • 手动让从机变为主机 , 需要人工手动设置十分不方便

    slaveof on one
    # 让自己变为主机
    
  • 使用哨兵根据投票自动选择从机变为主机 , 哨兵模式更加适用。

带哨兵模式的主从复制

​ 哨兵模式是一种特殊模式,哨兵是一个独立的进程,作为进程独立运行,原理是哨兵通过发送命令,等待redis服务器响应,从而判断服务器是否存货

单机哨兵

​ 哨兵向服务器发送信息,如果服务器没有一定时间内响应,就认为该服务器宕机。哨兵检测到master服务器宕机后,会自动将slave切换成master,通过发布订阅模式通知其他的从服务器,修改配置文件,让他们切换主机

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nTJyXBAA-1666273048113)(images/image-20211020213552176.png)]

单机哨兵宕机也会存在一定的风险,创建多个哨兵构建集群才是正解!

哨兵集群模式
  1. master宕机,sentinel检测到这个结果系统并不会马上进行failover(故障切换、失效备援)这个现象称为主观下线, 也就是不会马上切换主机。
  2. 等待其他哨兵也检测到主机不可用,sentinel之间会发起一次投票,(投票的结果由随机一个sentinel发起,进行failover操作)得到票数最多的从机就就切换成主机。
  3. 切换成主机后,通过发布订阅模式,让各个哨兵把自己监控的服务器实现切换主机,这个过程称为客观下线

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WsHEmdXe-1666273048113)(images/image-20211020214326017.png)]

单哨兵模式实现
创建哨兵配置文件 sentinel.conf
# sentinel.conf
sentinel monitor mymaster 127.0.0.1 6380 1
# sentinel monitor   mymaster(主机的名称,随便写)  主机IP  端口  
# 1 表示: (法定人数)至少需要 1 个哨兵同意的情况下,才可以让从机变为主机

有的redis目录下就有sentinel.conf文件只需要对其修改即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-paQMqXYr-1666273048113)(images/image-20211020221534343.png)]

启动哨兵模式
redis-sentinel sentinel.con

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lt5z7gA5-1666273048114)(images/image-20211020220030599.png)]

  • 启动sentinel成功之后看到,监控了6381、6382、6380的健康状态。
  • 端口为26379
  • 如果哨兵检测到master宕机,则会打印检测信息
测试master宕机

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pXr9KVMx-1666273048114)(images/image-20211020220506781.png)]

稍微等待一会,sentinel打出信息, 6380宕机,6382上位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-04zTOqQO-1666273048114)(images/image-20211020220851566.png)]

连接6382查看主从信息,发现6382变为主机

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q66RrOPO-1666273048114)(images/image-20211020221030567.png)]

如果6380恢复,那么6380是否还是主机呢?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5knfw0k-1666273048114)(images/image-20211020221307351.png)]

很明显,6380就算恢复,也只能是从机,无法恢复成主机。

多哨兵集群配置
多哨兵集群的配置和单哨兵是一样的
  • 复制三份sentinel1.confsentinel2.confsentinel3.conf即可

  • 修改sentinel.conf中的port段口号即可,默认端口号26379,三个不一样的端口号。

  • 监视主机的配置写法一样

    sentinel monitor mymaster 127.0.0.1 6379 2
    
哨兵模式优缺点

优点

  • 基于集群,基于主从复制,所有的主从配置的优点,它全有
  • 主从可以切换,故障可以切换,系统的可用性提高
  • 哨兵模式就是主从模式的升级,手动到自动,更加健壮

缺点

  • redis不好在线扩容,集群容量一旦达到上限,在线扩容就十分麻烦
  • 哨兵模式需要很多配置
    • 多哨兵,多端口配置复杂,一般由运维来配置

Redis缓存穿透、击穿、雪崩

服务三高
  • 高并发
  • 高可用
  • 高性能
Redis缓存

redis缓存的使用极大的提升了应用程序的性能和效率,特别是数据查询方面,但是也带来了许多问题,如数据一致性问题,对一致性要求高的不推荐适用缓存。

缓存穿透

​ 用户查询一个数据,redis数据库中没有,也就是缓存没命中,于是向持久层数据库查询,发现也没有,于是查询失败,用户很多的时候,缓存都没有命中,都请求持久层数据库,给持久层数据库造成巨大压力,称为缓存穿透。(由于缓存没有命中,大量的请求冲击数据库,导致缓存穿透)

解决方法
  • 布隆过滤器,在直达持久层的路径上加上过滤器
  • 缓存空对象,缓存中专门增加一个为空的请求
布隆过滤器

布隆过滤器是一种数据结构,对所有可能的查询参数以hash形式存储,在控制层进行校验,不符合则丢弃,从而避免了对底层存储系统查询压力

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WppOgu87-1666273048115)(images/image-20211021091043331.png)]

缓存空对象

​ 当持久化层不命中后,将返回的空对象存储起来,同时设置一个过期时间,之后再访问这个数据就从缓存中获取,保护持久层数据源

**[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zo1SLTeJ-1666273048115)(images/image-20211021091158848.png)]**

设置空缓存的问题
  • 存储空的key也需要空间
  • 对空值设置了过期时间,还会存在缓存层和存储层的数据有一段时间窗口不一致,对于需要保持一致性的业务会有影响
缓存击穿

例子微博服务器热搜,巨大访问量访问同一个key

​ 一个key非常热点,不停扛着大并发,集中对一个点进行访问,当个key失效的瞬间,持续大并发导致穿破缓存,直接请求数据库

​ 某个key在过期的瞬间,大量的访问会同时访问数据库来查询最新的数据,并且回写缓存,导致数据库瞬间压力过大

======================================

一句话说,就是某个热点key承受不住高压(或者突然过期),导致大量请求直接访问数据库,导致缓存穿透。

======================================

解决方案
  • 设置热点数据不过期,但是一直缓存会导致浪费空间
  • 加分布式锁:使用分布式锁,保证对于每个key同时只有一个线程查询后端服务,其他线程没有获得分布式锁的权限,只需要等待即可,这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大
缓存雪崩

在某一个时间段,缓存集中过期失效,redis宕机

产生雪崩的原因之一,设置缓存的存活时间较短,大并发访问时刚好都过期,直接访问了数据库,对数据库而言,会产生周期性压力波峰**,暴增时数据库可能会宕机**

==========================================

一句话:就是突然大量的缓存失效,大量数据访问数据库,数据库承受不住压力宕机了,导致其他所有服务不可用,就像雪崩一样。

==========================================

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xCBtM5hF-1666273048115)(images/image-20211021092838265.png)]

解决方法
  • 异地多活、增加redis集群服务器的数量
  • 加分布式锁、缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量,对某个key只允许一个线程查询数据和写缓存,其他线程等待
  • 限流降级、控制访问流量,对高并发的流量进行限制,并使用降级策略。
  • 数据预热,正式部署之前,把可能的数据提前访问一遍,可能大量访问的数据就会加载到缓存中,加载不同的key,设置不同的过期时间,让缓存时间尽量均匀
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值