Redis超详细入门(图文结合)原来redis这么简单

Redis入门

概述

redis简介

Redis 是一种开源(BSD 许可)、内存中数据结构存储,用作数据库缓存消息代理。Redis 提供了诸如 字符串散列列表集合、带范围查询的排序集合位图超级日志地理空间索引数据结构。Redis 内置了复制Lua 脚本LRU 驱逐事务和不同级别的磁盘持久化,并通过Redis SentinelRedis Cluster自动分区。

您可以 对这些类型运行原子操作,例如附加到字符串增加散列中的值将元素推入列表计算集合交集并集差集;或获取排序集中排名最高的成员

为了获得最佳性能,Redis 使用 内存数据集。根据您的用例,您可以通过定期将数据集转储到磁盘将每个命令附加到基于磁盘的日志来保留数据。如果您只需要一个功能丰富的网络内存缓存,您也可以禁用持久性。

Redis 还支持异步复制,具有非常快的非阻塞第一次同步,自动重新连接和网络拆分部分重新同步。

其他功能包括:

您可以从大多数编程语言中使用 Redis 。

Redis 是用ANSI C编写的,可在大多数 POSIX 系统(如 Linux、BSD 和 OS X)中运行,无需外部依赖。Linux 和 OS X 是 Redis 开发和测试最多的两个操作系统,我们推荐使用 Linux 进行部署。Redis 可能在 SmartOS 等 Solaris 派生系统中工作,但支持是尽力而为的*。没有对 Windows 构建的官方支持。

安装

  1. 下载安装包 注意:ContOS7支持5,如果需要安装更高版本需要升级gcc
  2. 解压 程序一般放在/opt目录下

在这里插入图片描述

  1. 解压后的文件

  2. 基本的环境安装

    yum install -y gcc-c++
    
    make
    
    make install
    

    因为redis是用c写的,所有需要安装c的编译环境

在这里插入图片描述

redis的默认安装路径:usr/local/bin

在这里插入图片描述

  1. 将redis配置文件复制到当前目录下
    在这里插入图片描述

  2. redis默认不是后台启动,如果后台启动,则需要修改配置

    在这里插入图片描述

端口号 6379

  1. 启动redis服务

在这里插入图片描述

  1. 连接测试

在这里插入图片描述

  1. 查看redis进程是否开启
    在这里插入图片描述

  2. 关闭redis服务

    shutdown
    
    exit
    

在这里插入图片描述

在这里插入图片描述

性能测试

  1. 使用redis-benchmark

语法

redis-benchmark [option] [option value]

可选参数如下

序号选项描述默认值
1-h指定服务器主机名127.0.0.1
2-p指定服务器端口6379
3-s指定服务器 socket
4-c指定并发连接数50
5-n指定请求数10000
6-d以字节的形式指定 SET/GET 值的数据大小2
7-k1=keep alive 0=reconnect1
8-rSET/GET/INCR 使用随机 key, SADD 使用随机值
9-P通过管道传输 请求1
10-q强制退出 redis。仅显示 query/sec 值
11–csv以 CSV 格式输出
12*-l*(L 的小写字母)生成循环,永久执行测试
13-t仅运行以逗号分隔的测试命令列表。
14*-I*(i 的大写字母)Idle 模式。仅打开 N 个 idle 连接并等待。
  1. 测试

    redis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 1000
    

在这里插入图片描述

redis基本操作

  1. redis 有16个数据库,默认使用第0个
  2. redis对大小写不敏感

命令:

select 进行切换数据库

DEL key key存在时删除

EXISTS key 判断key是否纯在

EXPIRE key seconds 给定key设置过期时间 (秒)

MOVE key db 将当前数据库的key移到给定的数据库中

TTL key 返回key的剩余生存秒

RENAME key newkey 修改key名字

TYPE key 返回key所对应值的类型

FLUSHALL 清空所有数据库

FLUSHDB 清空当前的数据库

127.0.0.1:6379> set name "zishibushui" #设置key-value
OK
127.0.0.1:6379> select 2 #切换数据库2
OK
127.0.0.1:6379[2]> keys * #查看所有key
(empty list or set)
127.0.0.1:6379[2]> set age 12
OK
127.0.0.1:6379[2]> keys *
1) "age"
127.0.0.1:6379[2]> select 0
OK
127.0.0.1:6379> keys *
1) "name"
2) "myset:__rand_int__"
3) "counter:__rand_int__"
4) "mylist"
5) "key:__rand_int__"
127.0.0.1:6379> DEL "myset:__rand_int__" #删除该key
(integer) 1
127.0.0.1:6379> DEL ["counter:__rand_int__","mylist"] #好像不能这样删除多个?
Invalid argument(s)
127.0.0.1:6379> EXISTS "mylist" #判断是否存在该key
(integer) 1
127.0.0.1:6379> EXPIRE "mylist" 10  #设置过期时间
(integer) 1
127.0.0.1:6379> keys *
1) "name"
2) "counter:__rand_int__"
3) "key:__rand_int__"
127.0.0.1:6379> RENAME "key:__rand_int__" "key3" #修改key名称
OK
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> EXPIRE key3 20
(integer) 1
127.0.0.1:6379> ttl key3
(integer) 2  #还剩2秒过期
127.0.0.1:6379> ttl key3
(integer) -2 #已被删除
127.0.0.1:6379> MOVE name 2 #将name key 移到数据库2中
(integer) 1
127.0.0.1:6379> keys* 
(error) ERR unknown command `keys*`, with args beginning with: 
127.0.0.1:6379> keys *
1) "counter:__rand_int__"
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> keys *
1) "age"
2) "name"
127.0.0.1:6379[2]> FLUSHALL
OK
127.0.0.1:6379[2]> keys *
(empty list or set)

Redis是单线程的

Redis很快,是居于内存操作,所以CPU不是redis的瓶颈,Redis的瓶颈是根据机器的内存和网络宽带。

Redis为什么单线程还这么快

1、误区1:高性能的服务器一定是多线程? ❌

2、误区2:多线程一定比单线程效率高? ❌

速度:CPU > 内存 > 硬盘 。但是多线程(CPU上下切换 是耗时的)

Redis是将所有数据都放在内存里,所以使用单线程去操作效率是最高的,多线程(CPU上下切换 :是耗时的操作!!!)对于内存系统来说,如果没有上下文切换效率就是最高的。多次读写都是在一个CPU上,在内存情况下,这就是最佳的方案。

Redis五大基本类型

1、String 类型

命令:

SET key value 指定key的值

GET key 获取指定key的值

GETRANGE key start end 返回key中字符串值得子字符

GETSET key value 将给定得key设置为value,并返回key得旧值

MSET key1 [key2..] 获取所有、一个或多个给定的值

SETNX key value 只有key不存在时,设置key得值

STRLEN key 获取key储存得value得长度

MSET key value[key value...] 同时设置一个或多个key-value

MSETNX key value[key value...] 同时设置一个或多个key-value,当且仅当所有key都不纯在时,否则都不成功

APPEND key value 如果key存在并且是一个字符串,将value添加到原来得末尾

127.0.0.1:6379> set name zishibushui
OK
127.0.0.1:6379> set name kangxiaozi
OK
127.0.0.1:6379> get name 					#值会被覆盖
"kangxiaozi"
127.0.0.1:6379> set name1 zishibushui
OK
127.0.0.1:6379> set name2 kangxiaozi
OK
127.0.0.1:6379> get name1
"zishibushui"
127.0.0.1:6379> getrange name2 0 -1         	#获取key所有的字符
"kangxiaozi"
127.0.0.1:6379> getrange name1 0 -1
"zishibushui"
127.0.0.1:6379> getrange name 0 5				#获取下标0到5的字符。[0,5]闭区间
"kangxi"
127.0.0.1:6379> getrange name1 0 5
"zishib"
127.0.0.1:6379> getset name2 hukangzhe   #先get再set
"kangxiaozi"
127.0.0.1:6379> getset name3 xiaoztongxue 
(nil)
127.0.0.1:6379> get name2
"hukangzhe"
127.0.0.1:6379> get name3
"xiaoztongxue"
127.0.0.1:6379> mget name1 name2 name3 name4 #获取多个key的值
1) "zishibushui"
2) "hukangzhe"
3) "xiaoztongxue"
4) (nil)
127.0.0.1:6379> setnx name1 zishibushuishui #只有当key不存在时,设置值
(integer) 0									#失败
127.0.0.1:6379> set name4 suyu
OK
127.0.0.1:6379> append name4 suyu		#向末尾添加value
(integer) 8
127.0.0.1:6379> mget name1 name2 name3 name4
1) "zishibushui"
2) "hukangzhe"
3) "xiaoztongxue"
4) "suyusuyu"
127.0.0.1:6379> mset name5 xiao name6 yang  #多个设置
OK
127.0.0.1:6379> mget name1 name2 name3 name4 name5 name6
1) "zishibushui"
2) "hukangzhe"
3) "xiaoztongxue"
4) "suyusuyu"
5) "xiao"
6) "yang"

2、List(列表)

在这里插入图片描述

------------------------------增删改查------------------------------

LPUSH key value1 [value2] 从左边添加值

LPOP key 移除并获取列表的第一个元素

RPUSH key value1 [value2] 从右边添加值

RPOP key 移除列表的最后一个元素,返回值为移除的元素。

LINDEX key index 通过索引获取列表中的元素

LLEN key 获取列表长度

LREM key count value 移除列表中与参数value相同的值

  • count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。
  • count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。
  • count = 0 : 移除表中所有与 VALUE 相等的值。

LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除

LSET key index value 通过索引设置列表元素的值

LRANGE key start stop 获取列表指定范围内的元素

LINSERT key BEFORE|AFTER pivot value 在列表的前面或者后面插入元素

###############################################################
#头部尾部添加 
#查询所有元素
127.0.0.1:6379> LPUSH list1 one two three #添加多个值
(integer) 3
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> RPUSH list1 zi shi bu shui #向尾部添加
(integer) 7
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "two"
3) "one"
4) "zi"
5) "shi"
6) "bu"
7) "shui"
###############################################################
#移除
127.0.0.1:6379> LPOP list1		#移除第一个(最左边)元素,并返回
"three"
127.0.0.1:6379> RPOP list1		#移除最后一个(最右边)元素,并返回
"shui"
127.0.0.1:6379> LRANGE list1 0 -1
1) "two"
2) "one"
3) "zi"
4) "shi"
5) "bu"
###############################################################
#查询长度	LLEN
127.0.0.1:6379> Llen list1
(integer) 5				 #返回列表的长度
###############################################################
#精准移除  LREM key count value
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "three"
3) "one"
4) "two"
5) "one"
6) "zi"
7) "shi"
8) "bu" 
127.0.0.1:6379> LREM list1 2 one   #count>0,从表头开始搜索,移除2个one
(integer) 2					#表示移除了2个
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "three"
3) "two"
4) "zi"
5) "shi"
6) "bu"
127.0.0.1:6379> LREM list1 -2 zi  #从表尾开始搜索,移除2个zi,如果zi小于2也移除
(integer) 1					#表示移除了1个
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "three"
3) "two"
4) "shi"
5) "bu"
###############################################################
#插入  LINSERT key BEFORE|AFTER pivot value
127.0.0.1:6379> LINSERT list1 before two one #在two前面插入one
(integer) 6
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "three"
3) "one"
4) "two"
5) "shi"
6) "bu"
###############################################################
#截断 LTRIM key start stop
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "three"
3) "one"
4) "two"
5) "shi"
6) "bu"
127.0.0.1:6379> LTRIM list1 1 5  #截断下标1到5,闭区间[1,5]
OK
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "one"
3) "two"
4) "shi"
5) "bu"
###############################################################
# 更新 LSET key index value
#RPOPLPUSH 移除列表最后一个值,到新的列表
127.0.0.1:6379> LSET list1 4 jiao  #通过下标更改值
OK
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "one"
3) "two"
4) "shi"
5) "jiao"
127.0.0.1:6379> RPOPLPUSH list1 list3
"jiao"
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "one"
3) "two"
4) "shi"
###############################################################

问题:

​ redis 不是 key-value的键值对吗?可以可以是key对应列表。只能key是列表,value是列表中的值吗?

  • 并不能单纯get 列表,来获取列表的值
127.0.0.1:6379> keys *
1) "list1"
2) "l1"
3) "list2"
127.0.0.1:6379> get l1
"list1"
127.0.0.1:6379> get list1
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get list2
(error) WRONGTYPE Operation against a key holding the wrong kind of value

3、Set(集合)

无序不重复

------------------------------增删改查------------------------------

SADD key member1[mermber2] 向集合添加一个或多个成员

SCARD key 获取集合的成员数量

SMEMBERS key 获取所有成员

SISMEMBER key member 判断member是否是集合成员

SPOP key 移除并返回一个随机成员

SMOVE source destination member 将member从source集合移到destination集合

SREM key member1[member2] 移除一个或多个成员

SRANDMEMBER key [count] 返回一个或count个成员

----------------------------数学集合的交并补--------------------

SDIFF key1 [key2] 返回第一个集合与其他集合之间的差异。

SDIFFSTORE destination key1 [key2] 返回给定所有集合的差集并存储在 destination 中

SINTER key1 [key2] 返回给定所有集合的交集

SINTERSTORE destination key1 [key2] 返回给定所有集合的交集并存储在 destination 中

SUNION key1 [key2] 返回所有给定集合的并集

SUNION STORE destination key1 [key2] 所有给定集合的并集存储在 destination 集合中

###############################################################
127.0.0.1:6379> SADD myset hello   #添加一个值
(integer) 1
127.0.0.1:6379> SADD myset world and zishibushui  #添加多个值
(integer) 3
127.0.0.1:6379> SCARD myset      #查看set中的成员个数
(integer) 4
127.0.0.1:6379> SMEMBERS myset   #查看所有成员
1) "and"
2) "world"
3) "hello"
4) "zishibushui"
127.0.0.1:6379> SISMEMBER myset hello  #判断set是否包含值
(integer) 1
127.0.0.1:6379> SISMEMBER myset you
(integer) 0
###############################################################
#随机移除
127.0.0.1:6379> SPOP myset  	#随机移除一个值
"hello"
127.0.0.1:6379> SPOP myset 2   	#随机移除多个值
1) "and"
2) "zishibushui"
127.0.0.1:6379> SMEMBERS myset
1) "world"
###############################################################
#精准移除
#移动
127.0.0.1:6379> SMEMBERS myset
1) "my"
2) "hello"
3) "world"
127.0.0.1:6379> SREM myset hello #移除指定元素
(integer) 1
127.0.0.1:6379> SMOVE myset tempset my  #将my元素从myset移动到tempset
(integer) 1
127.0.0.1:6379> smembers myset
1) "world"
127.0.0.1:6379> SMEMBERS tempset
1) "my"
127.0.0.1:6379> 
###############################################################
#随机返回元素(并不是移除)
127.0.0.1:6379> SMEMBERS myset
1) "my"
2) "hello"
3) "world"
4) "zishibushui"
5) "your"
127.0.0.1:6379> SRANDMEMBER myset  #随机返回一个元素
"world"
127.0.0.1:6379> SRANDMEMBER myset 2  #随机返回两个元素
1) "world"
2) "your"
127.0.0.1:6379> SMEMBERS myset
1) "zishibushui"
2) "world"
3) "hello"
4) "your"
5) "my"
#####################################################
#数学集合的交并补							#tempste:{my}
											 #myset:{your,hello,world,zishibushui,my}
127.0.0.1:6379> SDIFF myset tempset    #差值
1) "your"
2) "hello"
3) "world"
4) "zishibushui"
127.0.0.1:6379> SINTER myset tempset #交值
1) "my"
127.0.0.1:6379> SUNION myset tempset	#并值
1) "zishibushui"
2) "world"
3) "hello"
4) "your"
5) "my"

4、Hash(哈希)

Redis hash 是一个string类型的field(字段)和value(值)的映射表,特别适合存储对象

------------------------------增------------------------------

HMSET key field1 value1[field2 value2] 设置多个值

HSET key field value

HSETNX key field value 只有当字段不存在时,设置

----------------------------------查-----------------------------------

HGET key field 获取字段的值

HMGET key field1 [field2] 获取所有给定字段的值

HGETALL key 获取所有的字段和值

HKEYS key 获取所有哈希表中的字段

HLEN key 获取哈希表中字段的数量

HVALS key 获取哈希表中所有值

HEXISTS key field 查看哈希表key中,指定的字段是否存在

------------------------------删----------------------------------------

HDEL key field1 [field2] 删除一个或多个字段

-----------------------------改-----------------------------------------

HINCRBY key field increment

HINCRBYFLOAT key field increment

5、ZSet(有序集合)

不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

ZADD key score1 member1[score2 member2] 向一个有序集合添加一个或多个成员

ZREM key member1 [member2] 移除一个或多个成员

ZREMRANGEBYLEX key min max 移除有序集合中给定的字典区间的所有成员

ZREMRANGEBYRANK key start stop 移除有序集合中给定的排名区间的所有成员

ZREMRANGEBYSCORE key min max 移除有序集合中给定的分数区间的所有成员

ZCARD key 获取有序集合的成员数

ZCOUNT key min max 计算在有序集合中指定区间的成员数

ZLEXCOUNT key min max 在有序集合中计算指定字典区间内成员数量

ZRANGE key start stop 通过索引区间返回有序集合指定区间内的成员

ZRANGEBYLEX key min max 通过字典区间返回有序集合的成员

ZRANGEBYSCORE key min max 通过分数返回有序集合指定区间内的成员

ZRANK key member1 返回有序集合中指定成员的索引

ZSCORE key member 返回成员的分数

ZREVRANK key member 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序

ZREVRANGEBYSCORE key max min 返回有序集中指定分数区间内的成员,分数从高到低排序

特殊类型

1、地理空间geospatial

  • GEOADD

  • GEODIST

  • GEOHASH

  • GEOPOS 返回由key处的排序集表示的地理空间索引的所有指定成员的位置(经度、纬度)。

  • GEORADIUS

  • GEORADIUSBYMEMBER

  • GEOSEARCH

  • GEOSEARCHSTORE

GEOADD key 经度 维度 名称

127.0.0.1:6379> GEOADD china:city 115.89 28.67 nanchang 121.47 31.23 shanghai
(integer) 2
127.0.0.1:6379> GEOADD china:city 118.76 32.04 nanjing
(integer) 1
127.0.0.1:6379> GEOADD china:city 114.08 22.54 shenzhen
(integer) 1

GEOPOS 获取经纬度

127.0.0.1:6379> GEOPOS china:city shenzhen
1) 1) "114.08000081777572632"
   2) "22.53999903789756587"
127.0.0.1:6379> GEOPOS china:city nanchang shanghai
1) 1) "115.88999837636947632"
   2) "28.66999910629679249"
2) 1) "121.47000163793563843"
   2) "31.22999903975783553"

GEODIST:获取两地之间的距离

默认单位米

  • m为米。
  • km为公里。
  • mi数英里。
  • ft为英尺。
127.0.0.1:6379> GEODIST china:city nanchang shanghai
"608368.9697"
127.0.0.1:6379> GEODIST china:city nanchang shanghai km
"608.3690"

GEORADIUS

根据 Redis 6.2.0,GEORADIUS 命令系列被视为已弃用。请在新代码中优先选择GEOSEARCHGEOSEARCHSTORE

  • WITHDIST: 同时返回返回的物品与指定中心的距离。距离以与命令的半径参数指定的单位相同的单位返回。
  • WITHCOORD: 同时返回匹配项的经纬度坐标。
  • WITHHASH:还以 52 位无符号整数的形式返回项目的原始 geohash 编码的排序集分数。这仅对低级黑客或调试有用,否则一般用户几乎没有兴趣。

命令默认是返回未排序的项目。可以使用以下两个选项调用两种不同的排序方法:

  • ASC:相对于中心,从最近到最远对返回的项目进行排序。
  • DESC:相对于中心,从最远到最近对返回的项目进行排序

默认情况下,该命令将项目返回给客户端。可以使用以下选项之一存储结果:

  • STORE:将项目存储在填充了其地理空间信息的排序集中。
  • STOREDIST:将项目存储在一个排序的集合中,以它们到中心的距离作为浮点数,以半径中指定的相同单位填充。
127.0.0.1:6379> GEORADIUS china:city 115.89 28.67 700 km WITHCOORD
1) 1) "nanchang"
   2) 1) "115.88999837636947632"
      2) "28.66999910629679249"
2) 1) "shanghai"
   2) 1) "121.47000163793563843"
      2) "31.22999903975783553"
3) 1) "nanjing"
   2) 1) "118.75999957323074341"
      2) "32.03999960287850968"


127.0.0.1:6379> GEORADIUS china:city 115.89 28.67 700 km WITHCOORD ASC
1) 1) "nanchang"
   2) 1) "115.88999837636947632"
      2) "28.66999910629679249"
2) 1) "nanjing"
   2) 1) "118.75999957323074341"
      2) "32.03999960287850968"
3) 1) "shanghai"
   2) 1) "121.47000163793563843"
      2) "31.22999903975783553"


127.0.0.1:6379> GEORADIUS china:city 114 28 700 km WITHDIST DESC
1) 1) "nanjing"
   2) "641.7613"
2) 1) "shenzhen"
   2) "607.3489"
3) 1) "nanchang"
   2) "199.4704"

GEORADIUSBYMEMBER

该命令与GEORADIUS完全一样,唯一的区别是,它不以经纬度值作为要查询的区域的中心,而是以排序集表示的地理空间索引中已经存在的成员的名称。

根据 Redis 6.2.0,GEORADIUS 命令系列被视为已弃用。请在新代码中优先选择GEOSEARCHGEOSEARCHSTORE

127.0.0.1:6379> GEORADIUSBYMEMBER china:city nanchang 700 km  WITHDIST DESC
1) 1) "shanghai"
   2) "608.3690"
2) 1) "nanjing"
   2) "465.1110"
3) 1) "nanchang"
   2) "0.0000"

GEOHASH

返回有效的Geohash字符串,表示一个或多个元素在表示地理空间索引的排序集合值中的位置(其中元素是使用GEOADD添加的)

将二维的经度转成一维字符串

#如果这两个字符越接近,就代表距离越近
127.0.0.1:6379> GEOHASH china:city nanchang shanghai
1) "wt47j5hwbe0"
2) "wtw3sj5zbj0"

GEO底层的实现原理就是Zset

一些Zset操作GEO

127.0.0.1:6379> ZRANGE china:city 0 -1  #查看所有元素
1) "shenzhen"
2) "nanchang"
3) "shanghai"
4) "nanjing"
127.0.0.1:6379> ZREM china:city nanjing #移除一个元素
(integer) 1
127.0.0.1:6379> ZRANGE china:city 0 -1
1) "shenzhen"
2) "nanchang"
3) "shanghai"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子时不睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值