fuxi

0Zookeeper:
ZooKeeper的介绍:是一个分布式的协调服务框架,可以解决分布式环境常见的问题
Zookeeper的作用:1.集群的管理问题,能够通过一定的机制来检测到集群中节点的变化状态,是工作还是宕机。2。集群的统一配置文件3.实现主备切换,避免单点问题4.统一的命名问题5.分布式锁。
Zookeeper单机模式的安装:准备虚拟机,关闭防火墙—安装并配置jdk1.6以上—上传zookeeper安装包—解压安装包—进入zookeeper目录下的conf目录。有一个zoosample.cfg文件,复制一份命名为zoo.cfg—进入bin目录启动zookeeper zkService.sh start —进入客户端操作zookeeper zkCli.sh
Zookeeper集群的搭建::准备虚拟机,关闭防火墙—安装并配置jdk1.6以上—上传zookeeper安装包—解压安装包—进入zookeeper目录下的conf目录。有一个zoosample.cfg文件,复制一份命名为zoo.cfg—编辑zoo.fig—创建一个tmp目录下创建一个文件myid 编辑文件,添加当前的节点编号—进入bin目录开启zookeeper集群
Zookeeper的选举机制:分两个阶段

  1. 数据恢复阶段,在这个阶段,每台zk服务器要找到自己拥有的最大的事务id(从配置的数据目录中进行恢复)即找到自己拥有的最新的事务
  2. 选举阶段,每台zk服务器都会提交一份选举协议
     自己拥有的最大事务id
     自己的选举id(myid文件里的数据)
     逻辑时钟值,这个值是确保多台zk服务器在同一轮选举中
     当前zk服务器的状态:Looking选举状态 leader领导状态 follower从属状态 observer观察者状态
  3. 选举过程:首先比较最大事务id 谁大谁leader。因为事务id越大,拥有的数据越新
    如果事务id选不出来,就比较选举id,谁大谁leader
    ZAB协议:为Zookeeper专门设计的一种支持崩溃恢复的原子广播协议。
    包括两种基本的模式:消息原子广播(保证数据一致性)
    崩溃恢复(防止单点问题)
    协议的好处:对于事务的提交要满足过半性,好处在于解决zk服务器之间的同步阻塞问题,而且底层支持崩溃恢复,避免leader的单点故障问题,ZAB协议可以确保zk服务器集群的数据一致性,即客户无论从哪台zk服务器读取,数据都是一致的

Hadoop:
Hadoop的组成:HDFS 用于分布式文件的存储 MapReduce用于数据的计算 Yarn 进行任务调度
伪分布式的安装:准备虚拟机,关闭防火墙。安装jdk1.6以上-----配置主机名----配置hosts----配置免密码互通----上传安装Hadoop----配置Hadoop(1.修改hadoop-env.sh文件 主要是修改java_home的路径2.修改core-site.xml文件,添加namenode配置,文件存储位置配置3.修改hdfs-site.xml文件配置自身在内的备份副本数量4.修改mapred-site.xml文件,配置mapreduce运行在yarn上5.修改yarn-site.xml文件6.修改slaves.hadoop本身是一个主从结构7.配置hadoop环境变量8.格式化namenode)-----启动hadoop, start-all.sh
HDFS:分布式文件的存储。为保证数据的可靠性和读取性,HDFS对数据进行切块后进行复制并存储在集群的多个节点上。HDFS中存在一个名字节点namenode和若干个数据节点datanode.
优点:支持超大文件,检测和快速应对硬件故障,流式数据访问,高容错性
缺点:不支持超强的事务,低延迟数据访问,大量的小文件的处理
Block: 数据块Block是HDFS中存储文件的最基本的存储单位
在HDFS中存储的文件都是超大数据文件,我们可以把这个超大规模的文件以一个标准分成几块,分别存储在不同的磁盘上,这个标准就是Block
好处:文件可以保存在不同的磁盘上
简化存储系统,这样不需要管理文件,而是管理文件块就可以了
有利于数据的复制,在HDFS系统中,一个数据节点一般会复制3份
NameNode: 存储元数据信息、元数据保存在内存中以及磁盘中、保存文件、block/datanode之间的映射关系
SecondaryNameNode不是NameNode的备份,而是协助NameNode进行元数据合并。
合并过程:
达到合并条件后,snn会将nn中的fsimage和edits通过网络传输拷贝过来,同时nn中会创建一个新的edits.new文件,新的读写请求会写入这个edits.new中,在snn中将拷贝过来的fsimage和edits文件合并为一个新的fsimage文件,最后snn将合并成的新的fsimage文件拷贝回nn中代替原有的fsimage,nn将edits.new改为edits
Datanode: 在hadoop中,数据是以block的形式存储在DataNode中的,DataNode节点会不断的向NameNode节点发送心跳报告。
初始化时,每个数据节点将当前写存储的数据块告知NamwNode节点,通过心跳机制保持联系,并接受nameNode节点的指令,创建、移除或者删除本地磁盘上的数据块
HDFS的读流程:
 使用HDFS提供的客户端开发库Client,向远程的NameNode发起RPC请求。
 NameNode会视情况返回文件的部分或者全部block列表,对于block,都会返回有该block拷贝的DataNode地址
 客户端开发库Client会选取离客户端最近的DataNode来读取block。如果客户端本身就是DataNode,就从本地直接读取数据
 读取完当前block数据后,关闭与当前DataNode的连接,并为读取下一个block找最佳的DataNode
 当读取完列表的block的数据后,文件还没有读完,会继续向NameNode获取下一批的block列表
 读取完一个block都会进行checksum验证,如果读取DataNode时出现错误,会通知NameNode,再从下一个DataNode继续读
 当文件最后一个块也读取完毕后,datanode会连接NameNode告知关闭文件。
HDFS的写流程:
 使用HDFS提供的客户端开发库Client,向远程的NameNode发起RPC请求。
 NameNode会检测要创建的文件是否存在,创建者是否有权进行操作。成功会为文件创建一个记录,否则会让客户端抛出异常
 客户端将文件自己手动切块,然后将块放入packets中,然后利用packets将切好的文件块传入到dataNode中
 DataNode会将收到的packets转化为block进行存储。通过管道的形式写入,当全部写入后,会向客户端发送一个ack通知,客户端再向NameNode发送通知关闭连接。
 传输过程中,如果某个dataNode出现故障,通道会关闭,dataNode会移除,分配一个新的进行传输。
MapReduce:是一个分布式计算框架,由map和reduce组成。
Mapreduce原理:文件存储到HDFS,进行切片处理,每个文件块对应一个Map. Map通过键值对获取数据,键为数据的偏移量,值为读取的这一行的数据。Map根据自己写入的逻辑,对这些key,value进行处理,转换成新的key,value。通过洗牌对新的key,value进行分区管理,将相同的键所对应的值放到一块儿。Reduce自动去获取这些分区后的集合,根据自己写的逻辑进行处理,转换成新的key,value输出到HDFS中。
MR的序列化机制:map和reduce是通过RPC请求来处理对象的,Hadoop没有使用java的原生的序列化,它的底层是通过AVRO实现序列化的,只需要对象的类实现Writable接口
MR的内部执行流程:客户端提交一个MR的jar包给JobClient,JobClient通过RPC和ResourceManger进程通信,返回一个存放jar包的地址,client将jar包写入到HDFS中开始提交任务。ResourceManger进行初始化操作,读取HDFS上要处理的文件,开始计算输入分片。每一个分片对应一个MapperTask。NodeManger通过心跳机制领取任务,下载需要的jar包,配置文件。Nodemanger启动一个java子进程用来执行具体的任务。将结果写入到HDFS中。
Map阶段:

  1. 输入分片(inputsplit),这个时候就是输入数据的时候,会通过内部计算对数据进行逻辑上的分片,默认情况下这里的分片与HDFS文件中的分块是一致的。每个分片也就对应着一个mapper任务。
  2. Mapper将切片的数据输入到map函数中进行处理。
  3. Buffer函数将输出结果首先放入buffer(缓冲区)中为后面的操作(也就是写入硬盘)做准备。这里着重介绍一下buffer。Buffer从逻辑上来说是一个环形的缓冲区默认大小为100M,当第一次输入的数据超过它容量的80%这个阈值的时候(80%是他的溢写比)就会自动写入硬盘。就在它写入硬盘的时候程序会继续往剩余的20%的空间写数据。所有这样可以动态的写入更多的数据。但是一旦整个缓冲区写满的话,写入程序将会挂起直到缓冲区的数据都写完了写入程序将再次开启向缓冲区中写数据。
  4. 溢写(spill),在达到缓冲区容量的阈值时,环形缓冲区的数据会写到硬盘上,这个过程叫做溢写。这时会伴随着溢写列的操作,分区,排序,合并的操作。每一个溢写操作对应生成一个文件,也就是一个mapperTask会对应着多次溢写也就会处理多个文件。
     分区(partition),默认的分区是hash分区这样会保证所有相同的key就会存储在一起。我们也可以基于各种意义进行分区,这样具有相同意义的key会存储在一起。同时指出,一个分区对应一个Reduce。
     排序(sort)按照一定的规则按照键排序,这样key相同的数据就会排在一起,patition内部会整体有序。必须实现Comparable接口实现comableTo方法。
     合并(Combiner),程序在后台开启了一个线程Combiner,提前将key值相同的数据合并起来,减少往硬盘上写数据节省了空间。这些合并的数据会通过网络传输到Reduce相关的节点上,节省网络的开销。
  5. 归并(merge),将spill写入磁盘形成的小文件合并成一个大文件。
    Reduce阶段:
  6. 获取数据(fetch)reduce会主动向map阶段产生的数据中获取属于自己的数据,也就是每一reduce对应特定分区(patitiion)的数据。
  7. 归并(merge)将这些零散的数据再次合并,与前面的归并不同,这里的合并产生的不是一个大文件。
  8. 分组(group)分组和分区是不同的,分区的目的是根基key值决定Mapper输出的记录会被哪个reduce所获取,分组常常在分区内部进行。
  9. Reduce将这些数据输入reduce函数中进行计算处理,将最后结果存入到HDFS中。
    HDFS小文件的处理:
  10. Hadoop Archive 是一个高效的将小文件放入HDFS块中的文件存档工具,能够将多个小文件打包成一个HAR文件,减少nameNode内存使用的同时,仍然允许对文件进行透明的访问。
  11. 开启Hadoop的JVM重用机制,避免海量小文件带来的JVM频繁起停
  12. 将多个小文件合成一个文件,可以减少map的任务数量
    Hadoop防止数据倾斜:
  13. 常用合并来减少输入到reduce的数据,防止数据倾斜
  14. 在数据通过远程到达reduce端进行处理的时候,可以合理的设置归并排序的次数。
  15. 设置reduce的个数,来均衡原来输入到一个reduce上的数据,防止数据倾斜。
    Yarn机制:Yarn是资源协调者,主要负责资源的调度,与其他两个组件相互独立。

Flume介绍:是一个日志采集工具,具体来说他是一个分布式的能够从不同的来源收集、聚集和移动日志文件用以集中管理的系统。核心思想就是从不同的数据源(比如说远程的http请求,监听远程的日志文件)获得数据然后放入数据中转站。
Flume的特点:复杂流动(多级流动、扇入、扇出、故障转移和失败处理)、可靠性、可恢复(通道可以以内存或文件的方式实现)
核心组件:Agent 数据收集的基本单元,由Source Channel Sink组成。多个Source之间可以连接,形成复杂的日志流动的网络。
Source: 用来连接数据的源头与中转站的通道
常见的数据源有:
Avro Source:可以理解为序列化,可以接收外部Avro的数据流
Spooling Directry Source:允许你将将要收集的数据放置到指定的目录中,Source监视该目录,并解析新文件的出现。注意的是放置到目录下的文件不能修改,而且也不能产生重名文件,否则flume会报错。组件的名称 spooldir 要监控的文件
Channel: 数据的中转站,可以理解为一个“蓄水池”
MemoryChannel:存储在内存中,断电会丢失数据,速度快,适合需要高吞吐量可以忍受丢失数据的场景
FileChannel:存储在硬盘中,速度慢但是具有可靠性。
Spillable MemoryChannel:可溢写的内存通道,先存储在通道中,当有大量的并发数据时,将多出来的数据写入提前准备好的磁盘中,数据不会丢失
Sink :用来将中转站的内容输出到目的地的管道
Logger Sink :以日志的方式输出,这种输出常常用于调试
File Roll Sink:将数据输出到本地指定的文件夹中
HDFS Sink:将数据存储在HDFS中
Avro Sink:将数据以序列化的形式输出,通常用于多级流动

  Selector:选择器,主要实现扇出过程中按照指定方式分发数据,默认为复制机制。配置后为多路复用
  Interceptor:拦截器,生产中不是所有的数据都是我们想要的,所以要过滤掉一些我们不感兴趣的数据。或者说将一些数据拦截下来后进行一系列的操作后在放行,就用到了拦截器。
       TimeStamp Interceptor:它将会把事件拦截下来并且在事件的头中添加一个时间戳信息
       Host Interceptor:它会将事件拦截下来并且在事件的头中添加主机名或者IP信息
       Static Interceptor:它将事件拦截下来然后添加指定的头信息(key-value的方式)
       UUID Interceptor:它会把事件拦截下来然后在头中添加一个UUID字符串
       Regex Filter Interceptor:会把事件拦截下来看其中的内容是否匹配正则表达式然后决定是否接受这个事件
  Process:处理器,用于实现失败恢复 负载均衡的组件。由于客户端会产生大量的日志数据,如果只分配给一个中心服务器的话就可能导致崩溃。可以通过process进行调度分配数据。
      失败恢复机制:process将会维护一个sink优先,当出现问题后向了一个sink传输
      负载均衡机制:动态切换对sink的指向,支持轮询或随机方式.负载均衡机制自带失败恢复能力
                     
-------------------------------------------------------------------

Hive的介绍:Hive本质是一个翻译器,就是将Hql语句翻译成MapReduce,通过执行MapReduce来对海量数据仓库进行处理,表面上就是一个数据仓库能够查询与分析数据。
与传统的数据库比较,Hive的主要特点:1.分析离线存储数据,不具有实时性2.不支持事务,由于是历史数据没有必要去增删改3.不支持修改4.有很多数据的冗余保障了系统的健壮性。
Hive的5条重要结论:1.Hive中的数据库就是底层HDFS中的一个【库名.db】文件夹
2.Hive中的表就是底层HDFS中的库名文件夹下以表名为名字的文件夹
3.Hive中的数据就是HDFS中Hive表对应的文件夹下的文件
4.Hive中的Hql语句会转化为底层的MR来执行
5.Hive中默认的数据库对应的就是HDFS中/user/hive/warehouse目录
Hive的元数据库:存储着Hive的元数据信息具体就是库,表,列等数据之间的关系的描述,默认存放在derby数据库中。Derby数据库是一个单用户数据库,每当在一个新文件夹下启动Hive的时候就会新建一个新的存储元数据的文件夹出来,造成了很大的不便。所以我们一般使用mysql来存储元数据信息。
Hive元数据库中重要的表:
DBS:存储了Hive中库相关的信息,包括库编号、库名称、库所有者、库对应在HDFS中的存储位置
TBLS:存储了Hive中表相关的信息,包括表的编号、所属库的编号、表所有者、表名称、表类型
COLUMNS_V2:存储了Hive表中对应列的信息
SDS:存储Hive表中对应在HDFS中的存储位置,包括表的编号,存储位置
Hive中的内部表和外部表:内部表就是通过Hive直接创建一个表这时HDFS中也就会相应的创建一个文件,它是先有的表后有的数据,删除内部表,内部表删除元数据,对应的HDFS中表对应的文件夹和其中的数据也会被删除。外部表就是在真实开发中,很可能HDFS中已经有了数据,希望通过Hive直接使用这些数据作为表的内容,可以创建表关联这些数据,这种表就是外部表。先有数据后有表。外部表删除时只会删除元数据,HDFS中的数据不会删除。
创建外部表:create external table teacher (id int,name string) row format delimited fields terminated by ‘|’ location ‘/teacher’;
Hive中的分区表:Hive分区表的出现是为了提高查询效率,它的思想与mysql中的BTree索引很像,如果我们要查询分区内的数据我们提前就可以过滤很大一大批数据。由全表遍历变为选择性遍历。分区表就是在表对应的文件夹下再建立对应的子文件夹,子文件夹下存放真实数据。
Hive中的分桶表:是一种更细粒度的数据分配方式,主要实现数据的抽样,方便进行数据测试。通过hash分桶算法将数据放在不同的桶中。分桶过程是在底层的MR中实现的。
Hive的函数:拥有内置函数,也可以自定义函数UDF. Hive还可以使用JDBC来连接
 创建一个普通的java文件,导入hive相关的包
 写一个类继承UDF
 在类中编写一个公有的方法,方法名必须为evaluate,返回值和参数列表任意。
 将写好的工程打jar包,上传到linux中
 在hive中注册jar add jar /路径;
 注册自定义函数 create temporary function 名字 as ‘所在的包.类名’;
 调用临时函数 select 名字();

HBase概述:是一个高可靠、高性能、面向列、可伸缩的分布式存储系统。可以存储半结构化、非结构化的数据。利用Zookeeper作为协调工具,以HDFS作为文件存储系统,以mapReduce来处理HDFS中的海量数据。
HBase的逻辑结构:行键(RoeKey):相当于HBase表中的主键,所有数据都要按照行键的字典顺序排序后存储。对HBase表中的数据的查询,有三种方式:根据指定行键查询 根据指定行键的范围查询 全表扫描查询
行键设置原则:行键必须唯一才能唯一标识数据 必须有意义方便数据的查询 最好是字符串类型 做好具有固定的长度 不宜过长
列族(ColumnFamily):列族是HBase表从纵向来切分的逻辑结构,一个列族包含若干列,是HBase元数据的一部分
列:一个列族中包含多个列,在创建HBase表时不需要创建列,因为它可以在表创建之后动态的添加,不属于元数据的一部分。
单元格和时间戳:在HBase表中,行和列交汇得到HBase中的一个存储单元,在这个存储单元中可以存储数据的多个版本,这些版本通过时间戳来区分。通过行键、列族、列、时间戳确定的一个最小的存储数据的单元,叫做单元格。单元格中的数据都是以二进制形式存储的。
HBase的核心组件:HRegion:HBase起初只有一个HRegion保存数据,随着数据写入,HRegion越来越大,达到一定的阈值后自动分裂为两个HRegion,随着数据写入,HRegion会越越多,Hbase表中的数据被划分为若干个Hregion进行管理。
HRegion会分布式的存放在集群的HregionServer服务器中,从而实现分布式存储和负载均衡。
HRegion内部会有若干个store,Store的个数取决于列族的个数,一个Store内部又有一个memStore和若干个storeFile.storeFile本质上就是HDFS中的HFile文件。
HBase的写数据流程:当客户端联系HBase要写入一条数据时,根据表名和行键确定要操作的是哪个Hregion,找到存储着该Hregion的HregionServer服务器进行操作。根据要操作的列族找到对应的Store,向Store中的memStore中写入文件,并且在HLog中记录操作日志。之后返回写入成功,写入过程是基于内存的,性能好。

  1. 如果在写入时memStore满了怎么办?
    如果memStore被写满时。Store会自动又生成一个memStore继续工作。这个时候HBase会启动一个独立的线程,将满了的memStroe中的数据写入到HDFS中的HFile中,将数据持久化。
    在不停的产生HFile的过程中,同一个Store产生多个HFile中可能存在对同一个数据的不同的版本,其中有失效的数据,但是HDFS只能一次写入多次读取不能删除和修改,垃圾无法清除,降低查询性能。这个时候,HBase触发HFile的合并操作,将同一个Store产生的HFile合并成一个HFile,期间进行垃圾清理。当不停的合并达到一定大小的时候Hfile会拆分成若干个小Hfile,防止Hfile过大。
  2. 断电memStore丢失数据怎么办?
    HRegionServer中存在名为HLog的日志文件,在向memStore中写入数据的同时,数据需要写入HLog中记录操作日志,而在memStore满了溢写到HFile中完成之后,HBase会将把最后一条持久化到HDFS中的日志的编号记录到Zookeeper中的redo point。一旦数据丢失,只需要找到Zookeeper中找到最后持久化日志的编号,从HLog中将这个编号之后的数据恢复到内存中就可以找回所有丢失的数据。
    HBase的读流程:当客户端联系Hbase表示要读取某一张表时,HBase根据表和行键确定出HRegion,然后找到存储该HRegion的HRegionServer。根据要查找的列族,确定出要查找的Store,首先查看memStore中是否有要查找的数据,如果有,直接返回查询结果,如果在memStore中没有要查找的数据,那么查询该Store对应的所有的StoreFile.
    在这个过程中,解析StoreFile,先读取StoreFile中的Trailer块,找到DataBlockIndex,根据索引判断要找的数据在当前的StoreFile中是否存在,不存在直接返回空,存在的话根据索引快速找到对应的DataBlocks中的DataBlock返回。
    多个StoreFile可能返回多个DataBlock,之后在内存中将这些DataBlock信息合并完成查询。
    HBase的HRegion的寻址:在HBase表中有一张特殊的Hbase:meta表,表中存放着HBase的元数据信息(HBase中有哪些表,表中有哪些HRegion,Hregion分布在哪个HRegionServer中)。 在meta表中,只有一个HRegion,这个Hregion存放在某一个HRegionServer中,并且会将这个持有meta表的HregionServer的地址存放在Zookeeper中的meta-region-server节点下。
    每次读写时,先访问Zookeeper中的meta-region-server的值,然后根据值找到Meta表存储的HRegionServer,得到Meta表唯一个HRegion。根据该Hregion中的表和行键找到真正操作的HRegionServer.
    第二次之后,会将访问的地址存储在本地缓存中,下次操作不需要在来一次这样的寻址,提升性能。
    三种常见的存储系统:
  3. hash存储:hash存储是引擎,是哈希表的持久化实现,支持增删改以及随机读取操作。但是不支持顺序扫描
    如果不需要有序的数据遍历,哈希表是最好的选择。
  4. B树存储:是B树的持久化实现,不仅支持增删改读操作,还支持顺序扫描。
  5. LSM树存储:LSM树的存储引擎和B树存储事务引擎一样,同样支持增删改读操作和顺序扫描。LSM树读性能低,写性能高。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于微信小程序的家政服务预约系统采用PHP语言和微信小程序技术,数据库采用Mysql,运行软件为微信开发者工具。本系统实现了管理员和客户、员工三个角色的功能。管理员的功能为客户管理、员工管理、家政服务管理、服务预约管理、员工风采管理、客户需求管理、接单管理等。客户的功能为查看家政服务进行预约和发布自己的需求以及管理预约信息和接单信息等。员工可以查看预约信息和进行接单。本系统实现了网上预约家政服务的流程化管理,可以帮助工作人员的管理工作和帮助客户查询家政服务的相关信息,改变了客户找家政服务的方式,提高了预约家政服务的效率。 本系统是针对网上预约家政服务开发的工作管理系统,包括到所有的工作内容。可以使网上预约家政服务的工作合理化和流程化。本系统包括手机端设计和电脑端设计,有界面和数据库。本系统的使用角色分为管理员和客户、员工三个身份。管理员可以管理系统里的所有信息。员工可以发布服务信息和查询客户的需求进行接单。客户可以发布需求和预约家政服务以及管理预约信息、接单信息。 本功能可以实现家政服务信息的查询和删除,管理员添加家政服务信息功能填写正确的信息就可以实现家政服务信息的添加,点击家政服务信息管理功能可以看到基于微信小程序的家政服务预约系统里所有家政服务的信息,在添加家政服务信息的界面里需要填写标题信息,当信息填写不正确就会造成家政服务信息添加失败。员工风采信息可以使客户更好的了解员工。员工风采信息管理的流程为,管理员点击员工风采信息管理功能,查看员工风采信息,点击员工风采信息添加功能,输入员工风采信息然后点击提交按钮就可以完成员工风采信息的添加。客户需求信息关系着客户的家政服务预约,管理员可以查询和修改客户需求信息,还可以查看客户需求的添加时间。接单信息属于本系统里的核心数据,管理员可以对接单的信息进行查询。本功能设计的目的可以使家政服务进行及时的安排。管理员可以查询员工信息,可以进行修改删除。 客户可以查看自己的预约和修改自己的资料并发布需求以及管理接单信息等。 在首页里可以看到管理员添加和管理的信息,客户可以在首页里进行家政服务的预约和公司介绍信息的了解。 员工可以查询客户需求进行接单以及管理家政服务信息和留言信息、收藏信息等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值