Redis 入门文档

Redis 入门文档

第1章 NoSQL

1.1 NoSQL数据库

1.1.1 NoSQL是什么

(1)NoSQL(Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库。
(2)NoSQL不拘泥于关系型数据库的设计范式,放弃了通用的技术标准,为某一领域特定场景而设计,从而使性能、容量、扩展性都达到了一定程度的突破。
1.1.2 NoSQL的特点
(1)不遵循SQL标准
(2)不支持ACID
(3)远超于SQL的性能。
1.1.3 NoSQL的适用场景
(1)对数据高并发的读写
(2)海量数据的读写
(3)对数据高可扩展性的
1.1.4 NoSQL的不适用场景
(1)需要事务支持
(2)基于sql的结构化查询存储,处理复杂的关系,需要即席查询。
(3)用不着sql的和用了sql也不行的情况,请考虑用NoSql
1.2 NoSQL家族
1)Memcached
(1)很早出现的NoSQL数据库
(2)数据都在内存中,一般不持久化
(3)支持简单的key-value模式,数据类型支持单一
(4)一般是作为缓存数据库辅助持久化的数据库
2)Redis
(1)几乎覆盖了Memcached的绝大部分功能
(2)数据都在内存中,支持持久化,主要用作备份恢复
(3)支持丰富的数据类型,例如 string 、 list 、 set、zset、hash等
(4)一般是作为缓存数据库辅助持久化的数据库
3)mongoDB
(1)高性能、开源、模式自由的文档型数据库
(2)数据都在内存中,如果内存不足,把不常用的数据保存到硬盘
(3)虽然是key-value模式,但是对value(尤其是json)提供了丰富的查询功能
(4)支持二进制数据及大型对象
(5)可以根据数据的特点替代RDBMS(关系数据库管理系统),成为独立的数据库。或者配合RDBMS,存储特定的数据
4)HBase
(1)Hbase是Hadoop项目的数据库,主要用于对大量数据进行随机、实时的读写操作.
(2)Hbase能支持到数十亿行 × 百万列的数据表
5)Cassandra
(1)Cassandra用于管理由大量商用服务器构建起来的庞大集群上的海量数据集(PB级)
6)Neo4j
(1)Neo4j是基于图结构的数据库,一般用于构建社交网络、交通网络、地图等

第2章 Redis简介

2.1 Redis官网

(1)Redis官方网站 http://Redis.io
(2)Redis中文官方网站 http://www.Redis.net.cn

2.2 Redis是什么

(1)Redis是一个开源的key-value存储系统。
(2)它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set)和hash(哈希类型)。
(3)Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件
(4)支持高可用和集群模式。

2.3 Redis的应用场景

2.3.1 配合关系型数据库做高速缓存
(1)高频次,热门访问的数据,降低数据库IO
(2)经典的Cache Aside Pattern(旁路缓存模式)

2.3.2 大数据场景
1)缓存数据
(1)需要高频次访问
(2)持久化数据访问较慢

2)临时数据
(1)高频次
(2)读写时效性高
(3)总数据量不大
(4)临时性
(5)用key查询

3)计算结果
(1)高频次写入
(2)高频次查询
(3)总数据量不大

2.3.3 利用其多样的数据结构存储特定的数据
(1)最新N个数据  通过List实现按自然事件排序的数据
(2)排行榜,TopN  利用zset(有序集合)
(3)时效性的数据,比如手机验证码 Expire过期
(4)计数器,秒杀  原子性,自增方法INCR、DECR
(5)去除大量数据中的重复数据 利用set集合
(6)构建队列利用list集合
(7)发布订阅消息系统  pub/sub模式

第3章 Redis安装

3.1 关于Redis版本

不用考虑在Windows环境下对Redis的支持,Redis官方没有提供对Windows环境的支持,是微软的开源小组开发了对Redis对Windows的支持

3.2 安装

1)安装新版gcc编译器
[atguigu@hadoop102 ~]$ sudo yum -y install gcc-c++
2)上传redis-6.2.1.tar.gz安装包到/opt/software目录下
3)解压redis-6.2.1.tar.gz到/opt/module目录下
[atguigu@hadoop102 software]# tar -zxvf redis-6.2.1.tar.gz -C /opt/module/
4)之后进入安装包的src目录,编辑Makefile文件,修改软件安装路径如下:
[atguigu@hadoop102 src]$ vim Makefile

#修改如下
PREFIX?=/home/atguigu
5)在Redis的解压路径下执行编译和安装命令
[atguigu@hadoop102 redis-6.2.1]$ make && make install

假设改错了,需要重新编译的话,删除上一次编译的文件命令 make distclean

3.3 查看安装目录 /home/atguigu/bin
(1)redis-benchmark:性能测试工具,可以在自己本子运行,看看自己本子性能如何(服务启动起来后执行)
(2)redis-check-aof:修复有问题的AOF文件
(3)redis-check-dump:修复有问题的RDB文件
(4)redis-sentinel:启动Redis哨兵服务
(5)redis-server:Redis服务器启动命令
(6)redis-cli:客户端,操作入口

3.4 Redis的启动

1)拷贝一份redis.conf配置文件到工作目录
[atguigu@hadoop102 ~]$ mkdir myredis
[atguigu@hadoop102 ~]$ cd myredis
[atguigu@hadoop102 myredis]$ cp /opt/module/redis-6.2.1/redis.conf .
2)绑定主机IP,修改bind属性
[atguigu@hadoop102 myredis]$ vim redis.conf
bind 0.0.0.0
3)指定配置文件进行启动
[atguigu@hadoop102 myredis]$ redis-server redis.conf
3.5 客户端访问
1)使用redis-cli 命令访问启动好的Redis,默认端口为6379
[atguigu@hadoop102 myredis]$ redis-cli
127.0.0.1:6379>

2)如果有多个Redis同时启动,或者端口做了修改,则需指定端口号访问
[atguigu@hadoop102 myredis]$ redis-cli -p 6379
127.0.0.1:6379>
3)如果访问非本机redis,需要指定host来访问
[atguigu@hadoop102 myredis]$ redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379>
4)通过 ping 命令测试验证
127.0.0.1:6379> ping
PONG
3.6 关闭Redis服务
如果还未通过客户端访问,可直接 redis-cli shutdown
127.0.0.1:6379> shutdown
如果已经进入客户端,直接 shutdown即可.
[atguigu@hadoop102 myredis]$ redis-cli shutdown

3.7 Redis 默认16个库

1)Redis默认创建16个库,每个库对应一个下标,从0开始.
通过客户端连接后默认进入到0 号库,推荐只使用0号库.
127.0.0.1:6379>
2)使用命令 select 库的下标来切换数据库
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]>

3.8 Redis的单线程+多路IO复用技术

1)是什么
多路io复用是指使用同一个线程处理多个IO数据流. 多路IO复用是利用select、poll、epoll(不同的监控策略)可以同时监察多个流的IO事件的能力,在空闲的时候会把当前线程阻塞,当有一个或多个流由IO事件发生时,就从阻塞态中唤醒,处理就绪的流。
2)优势
多路IO复用的优势在于当处理事件的消耗对比IO几乎可以忽略不计时,可以使用单线程处理大量的并发IO,而不用消耗太多的CPU和内存.
3)新版Redis6.x
虽然io多路复用已经不错了,但是面临很多大键值的访问时,其中IO操作还是容易出现高延迟的问题,为了进一步优化,Redis 6.x把IO的部分做成允许多线程的模式.
这个IO部分只是处理网络数据的读写和协议解析,执行API命令仍然使用单线程。所以这个多线程并不会让redis存在并发的情况。
另外,多线程IO默认是不开启的,需要在redis配置文件中配置
io-threads-do-reads no
io-threads 4

第4章 Redis的五大数据类型

4.1 帮助手册

http://redisdoc.com/

4.2 redis键(key)

1)查看当前库的所有键
127.0.0.1:6379> keys *
2)判断某个键是否存在
127.0.0.1:6379> exists
3)查看键对应的value的类型
127.0.0.1:6379> type
4)删除某个键
127.0.0.1:6379> del
5)设置过期时间
127.0.0.1:6379> expire
6)查看过期时间,-1表示永不过期,-2表示已过期
127.0.0.1:6379> ttl
7)查看当前库中key的数量
127.0.0.1:6379> dbsize
8)清空当前库
127.0.0.1:6379> flushdb
9)清空所有库
127.0.0.1:6379> flushall
4.3 String
4.3.1 特点
(1)String是Redis最基本的类型,适合保存单值类型,即一个key对应一个value(2)String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
(3)一个Redis中字符串value最多可以是512M

4.3.2 常用操作

1)添加键值对
127.0.0.1:6379> set
2)获取键的值
127.0.0.1:6379> get
3)将给定的追加到原值的末尾
127.0.0.1:6379> append
4)获取值的长度
127.0.0.1:6379> strlen
5)当key不存在时设置key的值
127.0.0.1:6379> setnx
6)将key中存储的数字值增1
127.0.0.1:6379> incr
7)将key中存储的数字值减1
127.0.0.1:6379> decr
8)将key中存储的数字值按照指定步长增
127.0.0.1:6379> incrby <步长>
9)将key中存储的数字值按照指定步长减
127.0.0.1:6379> decrby <步长>
10)同时添加一个或者多个key
127.0.0.1:6379> mset
11)同时获取一个或者多个key的值
127.0.0.1:6379> mget
12)同时添加一个或者多个key,当且仅当所有给定的key都不存在
127.0.0.1:6379> msetnx
13)获取值的子串
127.0.0.1:6379> getrange
14)从指定的开始位置覆盖旧值
127.0.0.1:6379> setrange
15)同时设置值和过期时间
127.0.0.1:6379> setex
16)设置新值的同时获取旧值
127.0.0.1:6379> getset
4.4 List
4.4.1 特点
(1)单键多值
(2)Redis List是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
(3)它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差

4.4.2 常用操作

1)从左边插入一个或多个值
127.0.0.1:6379> lpush <element…>
2)从右边插入一个或多个值
127.0.0.1:6379> rpush <element…>
3)从左边删除一个值(值在键在,值光键亡)
127.0.0.1:6379> lpop
4)从右边删除一个值(值在键在,值光键亡)
127.0.0.1:6379> rpop
5)从key1列表右边删除一个值,插入到key2列表左边
127.0.0.1:6379> rpoplpush
6)按照索引下标范围获取元素(从左到右)
127.0.0.1:6379> lrange
7)按照索引下标获取元素(从左到右)
127.0.0.1:6379> lindex
8)获取列表长度
127.0.0.1:6379> llen
9)在指定的前面或者后面插入
127.0.0.1:6379> linsert before|after
10) 从左边删除count个指定的value
127.0.0.1:6379> lrem
4.5 Set
4.5.1 特点
(1)set中的元素是无序不重复的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,
(2)Redis的Set是string类型的无序集合。它底层其实是一个value为null的hash表,所以添加,删除,查找的复杂度都是O(1)。
4.5.2 常用操作
1)将一个或者多个member元素加入到集合中,已经存在的member将被忽略
127.0.0.1:6379> sadd <member…>
2)取出集合的所有值
127.0.0.1:6379> smemebers
3)判断集合是否包含指定的member,包含返回1,不包含返回0
127.0.0.1:6379> sismember
4)返回集合的元素个数
127.0.0.1:6379> scard
5)从集合中删除指定的元素
127.0.0.1:6379> srem <member…>
6)随机从集合中删除一个值,会从集合中删除删除的值
127.0.0.1:6379> spop
7)随机从集合中取出n个值,不会从集合中删除
127.0.0.1:6379> srandmember
8)返回多个集合的交集元素
127.0.0.1:6379> sinter <key…>
9)返回多个集合的并集元素
127.0.0.1:6379> sunion <key…>
10)返回多个集合的差集元素
127.0.0.1:6379> sdiff <key…>
4.6 Zset

4.6.1 特点

(1)Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分(score) ,这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了 。
(2)因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。
4.6.2 常用操作
1)往集合中添加指定的 member 及score
127.0.0.1:6379> zadd [ … ]
2)从集合中取出指定下标范围的数据,正序取
127.0.0.1:6379> zrange [WITHSCORES]
3)从集合中取出指定下标范围的数据,倒序取
127.0.0.1:6379> zrevrange [WITHSCORES]
4)从集合中取出指定score范围的数据,默认从小到大
127.0.0.1:6379> zrangebyscore [WITHSCORES]
5)从集合中取出指定score范围的数据,从大到小
127.0.0.1:6379> zrevrangebyscore [WITHSCORES]
6)给集合中指定member的score增加increment
127.0.0.1:6379> zincrby
7)删除集合中指定的member
127.0.0.1:6379> zrem <member…>
8)统计指定score范围的元素个数
127.0.0.1:6379> zcount
9)返回集合中指定member的排名,排名从0开始
127.0.0.1:6379> zrank
4.6.3 思考: 实现一个文章访问量的排行榜
(1)使用哪种类型存储?
(2)key怎么设计?
(3)value怎么设计?
(4)写入使用什么命令?
(5)查询使用什么命令?
4.7 Hash
4.7.1 特点
(1)Redis hash是一个键值对集合
(2)Redis hash的值是由多个field和value组成的映射表
(3) 类似Java里面的Map<String,Object>
4.7.2 分析一个问题: 现有一个User 对象,在Redis中如何存?
1)第一种方案: 用户ID为key ,VALUE为JavaBean序列化后的字符串

2)第二种方案: 用户ID+属性名作为key, 属性值作为Value.

3)第三种方案: 通过 key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题

4.7.3常用操作

1)给集合中添加指定的 -
127.0.0.1:6379> hset [ …]
2)给集合中添加指定的 - ,当指定的field不存在时
127.0.0.1:6379> hsetnx
3)取出集合中指定field的value
127.0.0.1:6379> hget
4)判断集合中是否存在指定的field
127.0.0.1:6379> hexists
5)列出集合中所有的field
127.0.0.1:6379> hkeys
6)列出集合中所有的value
127.0.0.1:6379> hvals
7)给集合中指定filed的value值增加increment
127.0.0.1:6379> hincrby

第5章 Redis的相关配置

1)计量单位说明,大小写不敏感

1k => 1000 bytes
1kb => 1024 bytes
1m => 1000000 bytes
1mb => 10241024 bytes
1g => 1000000000 bytes
1gb => 1024
1024*1024 bytes

units are case insensitive so 1GB 1Gb 1gB are all the same.

2)bind

默认情况bind=127.0.0.1只能接受本机的访问请求
不写的情况下,无限制接受任何ip地址的访问,产环境肯定要写你应用服务器的地址
如果开启了protected-mode,那么在没有设定bind ip且没有设密码的情况下,Redis只允许接受本机的请求
#bind 127.0.0.1
protected-mode no

3)port 服务端口号

port 6379

4)daemonize

是否为后台进程
daemonize yes
5)pidfile
存放pid文件的位置,每个实例会产生一个不同的pid文件
pidfile /var/run/redis_6379.pid
6)log file
日志文件存储位置
logfile “”
7)database
设定库的数量 默认16
databases 16
8)requirepass
设置密码
requirepass 123456

127.0.0.1:6379> set k1 v1
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth “123456”
OK
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
“v1”
9)maxmemory
设置Redis可以使用的内存量。一 旦到达内存使用上限,Redis将会试图移除内部数据,移除规则可以通过maxmemory-policy来指定。如果Redis无法根据移除规则来移除内存中的数据,或者设置了“不允许移除”,
那么Redis则会针对那些需要申请内存的指令返回错误信息,比如SET、LPUSH等。
maxmemory
10)maxmemory-policy
移除策略
maxmemory-policy noeviction

#volatile-lru:使用LRU算法移除key,只对设置了过期时间的键
#allkeys-lru:使用LRU算法移除key
#volatile-lfu :使用LFU策略移除key,只对设置了过期时间的键.
#allkeys-lfu :使用LFU策略移除key
#volatile-random:在过期集合中移除随机的key,只对设置了过期时间的键
#allkeys-random:移除随机的key
#volatile-ttl:移除那些TTL值最小的key,即那些最近要过期的key
#noeviction:不进行移除。针对写操作,只是返回错误信息
11)Maxmemory-samples
设置样本数量,LRU算法和最小TTL算法都并非是精确的算法,而是估算值,所以你可以设置样本的大小。一般设置3到7的数字,数值越小样本越不准确,但是性能消耗也越小。
#maxmemory-samples 5

第6章 Jedis

Jedis是Redis的Java客户端,可以通过Java代码的方式操作Redis
6.1 环境准备
1)添加依赖

redis.clients jedis

1)测试连通

public class JedisTest {
public static void main(String[] args) {
Jedis jedis = new Jedis(“hadoop102”,6379);
String ping = jedis.ping();
System.out.println(ping);
}
}

2)连接池

连接池主要用来节省每次连接redis服务带来的连接消耗,将连接好的实例反复利用

public static JedisPool pool = null ;

public static Jedis getJedis(){
if(pool == null ){
//主要配置
JedisPoolConfig jedisPoolConfig =new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10); //最大可用连接数
jedisPoolConfig.setMaxIdle(5); //最大闲置连接数
jedisPoolConfig.setMinIdle(5); //最小闲置连接数
jedisPoolConfig.setBlockWhenExhausted(true); //连接耗尽是否等待
jedisPoolConfig.setMaxWaitMillis(2000); //等待时间
jedisPoolConfig.setTestOnBorrow(true); //取连接的时候进行一下测试 ping pong
pool = new JedisPool(jedisPoolConfig,“hadoop102”,6379) ;
}

return pool.getResource();

}
public static void main(String[] args) {
//Jedis jedis = new Jedis(“hadoop202”,6379);
Jedis jedis = getJedis();
String ping = jedis.ping();
System.out.println(ping);
}

第7章 Redis 持久化

7.1 两种方式
Redis提供了2个不同形式的持久化方式 RDB 和 AOF。
RDB为快照备份,会在备份时将内存中的所有数据持久化到磁盘的一个文件中。
AOF为日志备份,会将所有写操作命令记录在一个日志文件中。
7.2 RDB(Redis Database)
7.2.1 是什么
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。
7.2.2 如何执行持久化
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
7.2.3 RDB文件
1)RDB保存的文件
在redis.conf中配置文件名称,默认为dump.rdb
dbfilename dump.rdb
2)RDB文件的保存路径
默认为Redis启动时命令行所在的目录下,也可以修改
dir ./
7.2.4 RDB保存策略
#save

#Will save the DB if both the given number of seconds and the given
#number of write operations against the DB occurred.

#In the example below the behaviour will be to save:
#after 900 sec (15 min) if at least 1 key changed
#after 300 sec (5 min) if at least 10 keys changed
#after 60 sec if at least 10000 keys changed
#Note: you can disable saving completely by commenting out all “save” lines.
save 900 1
save 300 10
save 60 10000

7.2.5 手动保存
(1)save: 只管保存,其它不管,全部阻塞
(2)bgsave:按照保存策略自动保存
(3)shutdown时服务会立刻执行备份后再关闭
(4)flushall时会将清空后的数据备份
7.2.6 RDB备份恢复
1)备份
将dump.rdb文件拷贝到要备份的位置
2)恢复
关闭Redis,把备份的文件拷贝到工作目录下,启动redis,备份数据会直接加载。
7.2.7 RDB其他配置
1)进行rdb保存时,将文件压缩
rdbcompression yes
2)文件校验
在存储快照后,还可以让Redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
rdbchecksum yes

7.2.8 RDB优缺点

1)优点:
节省磁盘空间,恢复速度快.
2)缺点:
虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改
7.3 AOF(Append Only File)
7.3.1 是什么
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
7.3.2 开启AOF
1)AOF默认不开启,需要手动在配置文件中配置
appendonly no
2)AOF文件
appendfilename “appendonly.aof”
3)AOF文件保存的位置,与RDB的路径一致
dir ./
7.3.3 AOF同步频率
#no: don’t fsync, just let the OS flush the data when it wants. Faster.
#always: fsync after every write to the append only log. Slow, Safest.
#everysec: fsync only one time every second. Compromise.

7.3.4 AOF文件损坏恢复

redis-check-aof --fix appendonly.aof
7.3.5 AOF备份
AOF的备份机制和性能虽然和RDB不同, 但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载
7.3.6 Rewrite
AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的重写,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof手动开始重写。
重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。
系统载入时或者上次重写完毕时,Redis会记录此时AOF大小,设为base_size,如果Redis的AOF当前大小>= base_size +base_size*100% (默认)且当前大小>=64mb(默认)的情况下,Redis会对AOF进行重写。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

7.3.7 AOF的优缺点

1)优点:
(1)备份机制更稳健,丢失数据概率更低。
(2)可读的日志文本,通过操作AOF文件,可以处理误操作。
2)缺点:
(1)比起RDB占用更多的磁盘空间
(2)恢复备份速度要慢
(3)每次写都同步的话,有一定的性能压力
(4)存在个别bug,造成恢复不能

7.4 持久化的优先级

AOF的优先级大于RDB,如果同时开启了AOF和RDB,Redis服务启动时恢复数据以AOF为准.

7.5 RDB和AOF用哪个好

(1)官方推荐两个都启用。
(2)如果对数据不敏感,可以选单独用RDB
(3)不建议单独用 AOF,因为可能会出现Bug。
(4)如果只是做纯内存缓存,可以都不用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值