Linux常见的物理设备数据备份和负载均衡模式

在早期互联网的技术发展中,已经在思考数据的一致性和高可用,以应对设备异常和负载容量问题。典型的就是磁盘和网卡,分别发展出raid技术和bond技术,能够针对磁盘和网卡进行扩展。虽然这些技术依然存在,由于分布式存储的发展,分布式高可用的发展已经从硬件阶段过渡到软件阶段,并且能够提供更加丰富的能力。以满足业务需求。


1. 磁盘的raid技术

raid技术分为2种

  • 软raid
  • 硬raid

1.1 硬raid

硬 RAID 拥有自己的 RAID 控制处理与 I/O 处理芯片,甚至还有阵列缓冲,对 CPU 的占用率和整体性能是三类实现中最优的,但实现成本也最高的。硬 RAID 通常都支持热交换技术,在系统运行下更换故障磁盘。
硬 RAID 包含 RAID 卡和主板上集成的 RAID 芯片, 服务器平台多采用 RAID 卡。 RAID 卡由 RAID 核心处理芯片( RAID 卡上的 CPU )、端口、缓存和电池 4 部分组成。其中,端口是指 RAID 卡支持的磁盘接口类型,如 IDE/ATA 、SCSI 、SATA 、SAS 、FC 等接口。

1.2 软raid

按照磁盘组合方式和IO方式的不同分为RAID0、RAID1、RAID2、RAID3、RAID4、RAID5、RAID6、RAID7、RAID01、RAID10
常用的是RAID0、RAID1、RAID5、RAID10

1.2.1 RAID0:无差错控制的带区组

RAID 0 (Redundant Array of Independent Disks)是一种将多个硬盘组合成一个逻辑单元的数据存储技术。在RAID 0中,数据被划分并分布在多个驱动器上,从而提供了更高的性能和存储容量。但是,与其他RAID配置不同,RAID 0不提供任何数据冗余或容错。这意味着如果一个硬盘故障,RAID 0中的所有数据将丢失。
在这里插入图片描述
要实现 RAID 0 必须要有两个以上硬盘驱动器,RAID 0 实现了带区组,数据并不是保存在一个硬盘上,而是分成数据块保存在不同驱动器上。因为将数据分布在不同驱动器上,所以数据吞吐率大大提高,驱动器的负载也比较平衡。如果刚好所需要的数据在不同的驱动器上效率最好。它不需要计算校验码,实现容易。它的缺点是它没有数据差错控制,如果一个驱动器中的数据发生错误,即使其它盘上的数据正确也无济于事了。不应该将它用于对数据稳定性要求高的场合。如果用户进行图象(包括动画)编辑和其它要求传输比较大的场合使用 RAID 0 比较合适。同时,RAID 可以提高数据传输速率,比如所需读取的文件分布在两个硬盘上,这两个硬盘可以同时读取。那么原来读取同样文件的时间被缩短为 1/2 。在所有的级别中,RAID 0 的速度是最快的。但是 RAID 0 没有冗余功能的,如果一个磁盘(物理)损坏,则所有的数据都无法使用。

如果两块硬盘:160G + 120G = 240G

1.2.1 RAID1:镜象结构

RAID 1是指计算机存储中的一种冗余配置,其中数据同时写入两个或多个硬盘驱动器。它也被称为磁盘镜像。在RAID 1中,两个驱动器具有相同的数据,因此如果一个驱动器故障,仍然可以从另一个驱动器访问数据。这提供了一定程度的数据保护和改进的读性能,尽管与非raid配置相比,写性能通常较慢。

在这里插入图片描述
对于使用这种 RAID 1 结构的设备来说,RAID 控制器必须能够同时对两个盘进行读操作和对两个镜象盘进行写操作。通过下面的结构图您也可以看到必须有两个驱动器。因为是镜象结构在一组盘出现问题时,可以使用镜象,提高系统的容错能力。它比较容易设计和实现。每读一次盘只能读出一块数据,也就是说数据块传送速率与单独的盘的读取速率相同。因为 RAID 1 的校验十分完备,因此对系统的处理能力有很大的影响,通常的 RAID 功能由软件实现,而这样的实现方法在服务器负载比较重的时候会大大影响服务器效率。当您的系统需要极高的可靠性时,如进行数据统计,那么使用 RAID 1 比较合适。而且 RAID 1 技术支持“热替换”,即不断电的情况下对故障磁盘进行更换,更换完毕只要从镜像盘上恢复数据即可。当主硬盘损坏时,镜像硬盘就可以代替主硬盘工作。镜像硬盘相当于一个备份盘,可想而知,这种硬盘模式的安全性是非常高的,RAID 1 的数据安全性在所有的 RAID 级别上来说是最好的。但是其磁盘的利用率却只有50%,是所有 RAID 级别中最低的。

如果两块硬盘:160G + 120G = 120G

1.2.1 RAID5:分布式奇偶校验的独立磁盘结构

RAID 5是一种数据存储配置,它在多个驱动器上使用条带化和分布式奇偶校验。它至少需要三个驱动器来设置,并且数据分布在阵列中的所有驱动器上。在驱动器发生故障时,奇偶校验信息可用于在替换驱动器上重新创建丢失的数据。
与单驱动器配置相比,这允许数据冗余并提高性能。但是,RAID 5有一个缺点,即由于需要计算和写入奇偶校验信息,它降低了写入性能。
在这里插入图片描述
从它的示意图上可以看到,它的奇偶校验码存在于所有磁盘上,其中的 p0 代表第 0 带区的奇偶校验值,其它的意思也相同。RAID5 的读出效率很高,写入效率一般,块式的集体访问效率不错。因为奇偶校验码在不同的磁盘上,所以提高了可靠性,允许单个磁盘出错。RAID 5 也是以数据的校验位来保证数据的安全,但它不是以单独硬盘来存放数据的校验位,而是将数据段的校验位交互存放于各个硬盘上。这样,任何一个硬盘损坏,都可以根据其它硬盘上的校验位来重建损坏的数据。硬盘的利用率为n-1。但是它对数据传输的并行性解决不好,而且控制器的设计也相当困难。RAID 3 与RAID 5 相比,重要的区别在于 RAID 3 每进行一次数据传输,需涉及到所有的阵列盘。而对于 RAID 5 来说,大部分数据传输只对一块磁盘操作,可进行并行操作。在 RAID 5 中有“写损失”,即每一次写操作,将产生四个实际的读/写操作,其中两次读旧的数据及奇偶信息,两次写新的数据及奇偶信息。RAID 5 的话,优点是提供了冗余性(支持一块盘掉线后仍然正常运行),磁盘空间利用率较高 (N-1/N) ,读写速度较快(N-1倍)。RAID 5 最大的好处是在一块盘掉线的情况下,RAID 照常工作,相对于 RAID 0 必须每一块盘都正常才可以正常工作的状况容错性能好多了。因此 RAID5 是 RAID 级别中最常见的一个类型。RAID 5 校验位即P位是通过其它条带数据做异或 (xor) 求得的。计算公式为 P = D0 xor D1 xor D2 … xor Dn,其中 p 代表校验块,Dn 代表相应的数据块,xor 是数学运算符号异或。

1.2.1 RAID 10/01:高可靠性与高效磁盘结构

RAID 10,也称为RAID 1+0,是一种结合了RAID 1(镜像)和RAID 0(条带)级别的RAID配置。它至少需要4个磁盘,并提供高水平的数据保护和性能。
在RAID 10配置中,数据在磁盘对之间进行镜像,然后在这些镜像集之间进行条带化。这既提供了冗余,又提高了读写速度。如果其中一个磁盘故障,镜像pair将继续工作,保证数据的可用性。如果镜像pair中的两个硬盘都故障,则会导致整个RAID组故障。
RAID 10通常被认为是最健壮、最可靠的RAID配置之一,它提供了出色的性能、高容错性和快速重建时间。它通常用于既需要数据保护又需要快速访问数据的环境中,例如数据库服务器和高性能计算系统。但是,与其他RAID级别(如RAID 5或RAID 6)相比,它确实需要更多的磁盘,并且可能更昂贵。

RAID 01是一种综合了RAID 0(条带化)和RAID 1(镜像)优点的RAID级别。在RAID 01中,多个硬盘驱动器被分成两个或更多个集,然后将它们分条在一起,以提高性能和容错性。
在RAID 01中,数据在多个硬盘上分条,以提高读写速度。此外,数据在这些条纹集之间进行镜像,以提供冗余。但是,RAID 01至少需要4个驱动器,因为它至少需要2个驱动器用于条带化,另外还需要2个驱动器用于镜像。
RAID 01的一个优点是它的高性能,因为数据可以同时从多个驱动器读取和写入。镜像特性还确保即使一个驱动器出现故障,数据仍然可用。但是,RAID 01是昂贵的,因为与其他RAID级别相比,它需要更多的驱动器。

RAID10与RAID01比较

  • RAID10是先做镜象,然后再做条带。 RAID01则是先做条带,然后再做镜象。 比如以6个盘为例,RAID10就是先将盘分成3组镜象,然后再对这3个RAID1做条带。RAID01则是先利用3块盘做RAID0,然后将另外3块盘做为RAID0的镜象。

下面以4块盘为例来介绍安全性方面的差别:

  • RAID10的情况, 我们假设当DISK0损坏时,在剩下的3块盘中,只有当DISK1一个盘发生故障时,才会导致整个RAID失效,我们可简单计算故障率为1/3。
  • RAID01的情况,我们仍然假设DISK0损坏,这时左边的条带将无法读取。在剩下的3块盘中,只要DISK2,DISK3两个盘中任何一个损坏,都会导致整个RAID失效,我们可简单计算故障率为2/3。
  • 因此RAID10比RAID01在安全性方面要强

从数据存储的逻辑位置来看

  • 在正常的情况下RAID01和RAID10是完全一样的,而且每一个读写操作所产生的IO数量也是一样的,所以在读写性能上两者没什么区别
  • 当有磁盘出现故障时,比如前面假设的DISK0损坏时,我们也可以发现,这两种情况下,在读的性能上面也将不同,RAID10的读性能将优于RAID01。

1.3 常用命令

1.3.1 mdadm命令使用说明

mdadm:模式化工具,为什么叫模式化呢?就是因为这个工具在使用的过程中有很多的模式,通过不同的选项能够进入不同的模式来对磁盘进行管理这个命令的语法格式:

mdadm [mode] [options]

它能够支持的RAID级别有:LINEAR, RAID0, RAID1, RAID4, RAID5, RAID6, RAID10,…

  • [mode]:模式,分为创建模式、管理模式、监控模式、装配模式这四种模式,分别对应的功能如下:
  1. 创建模式:用来创建磁盘阵列
  2. 管理模式:向磁盘阵列中添加或者删除磁盘
  3. 监控模式:监控磁盘阵列的工作情况
  4. 装配模式:像是备份一样,将原先的磁盘阵列或者一个正在使用的磁盘阵列的配置用于一个新的磁盘阵列中
  • raiddevice:/dev/md
  • component-devices:任意块设备,注意如果是分区的话,其分区类型要改为fd

1.3.2 创建模式

在日常的使用中首先是创建一个磁盘阵列,使用-C选项进入创建模式,然后跟上以下选项来完成各自的功能:

  • -n #:使用#个块设备来创建此RAID
  • -l #:指明要创建的RAID的级别
  • -a {yes|no}:自动创建目标RAID设备的设备文件
  • -c CHUNK_SIZE:指明块大小, 默认值为512K
  • -x #:指明空闲盘的个数

创建一个RAID0:

[root@localhost ~] # mdadm -C /dev/md0 -a yes -l 0 -n 2 /dev/sdb{1,2}
mdadm: Defaulting to version 1.2 metadata
mdadm: array  /dev/md0  started.

在这条命令中

  • “-C”是指进入创建模式;“ /dev/md0 ”是指定创建好的RAID0叫什么名字;
  • “-a”是指自动创建目标RAID设备的设备文件;
  • “-l”后头跟RAID的级别,如过创建RAID0就是0,如果创建RAID5就是5 ;
  • “-n” 使用2个块设备来创建此RAID;在最后跟上想要加入此磁盘阵列的磁盘

1.3.3 管理模式

在创建完磁盘阵列并使用了一段时间之后,突然发现一块磁盘不能使用了,那么我们需要将其移除,并添加一块新的磁盘,此时需要使用管理模式,选项如下:

  • -f:为指定的磁盘或分区添加损坏标记
  • -a:添加磁盘或分区到md设备中
  • -r:从md设备中移除磁盘或分区

假设现在sdb2磁盘发生了损坏,想要将其更换为sdb3磁盘,那么首先要做的是先将sdb2磁盘标记为损坏:

  1. 创建RAID5:
[root@localhost ~] # mdadm -C /dev/md0 -a yes -l 5 -n 3 /dev/sdb{1,2,3}
mdadm: Defaulting to version 1.2 metadata
mdadm: array  /dev/md0  started.
  1. 将RAID5中的sdb2磁盘标记为损坏状态
[root@localhost ~] # mdadm /dev/md0 -f /dev/sdb2
mdadm:  set  /dev/sdb2  faulty  in  /dev/md0
  1. 移除sdb2磁盘
[root@localhost ~] # mdadm /dev/md0 -r /dev/sdb2
mdadm: hot removed  /dev/sdb2  from  /dev/md0
[root@localhost ~] #
  1. 查看md0,发现sdb2已经被移除了(还可以使用mdadm -D /dev/md0 命令查看)
[root@localhost ~] # cat /proc/mdstat 
Personalities : [raid0] [raid6] [raid5] [raid4] 
md0 : active raid5 sdb3[3] sdb1[0]
       4190208 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3 /2 ] [U_U]
       
unused devices: <none>
[root@localhost ~] #
  1. 在移除了磁盘之后,可以将一块新的硬盘添加到md0中,在这里可以将刚才移除的sdb2磁盘添加到md0中
[root@localhost ~] # mdadm /dev/md0 -a /dev/sdb2
mdadm: added  /dev/sdb2
[root@localhost ~] #
  1. 此时再次查看,发现sdb2又回来
[root@localhost ~] # cat /proc/mdstat 
Personalities : [raid0] [raid6] [raid5] [raid4] 
md0 : active raid5 sdb2[4] sdb3[3] sdb1[0]
       4190208 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3 /3 ] [UUU]
       
unused devices: <none>
[root@localhost ~] #
  1. 在一个磁盘阵列不用了之后,可以使用mdadm -D md0 来将其停止
[root@localhost ~] # mdadm -D md0

1.3.4 监控模式

使用mdadm -F /dev/md0命令来进行磁盘阵列的监控

[root@localhost ~] # mdadm -F /dev/md0
Jun 21 12:50:01: Fail on  /dev/md0  /dev/sdb2
Jun 21 12:50:19: RebuildStarted on  /dev/md0  unknown device

1.3.5 装配模式

在日常的使用当中,我们可能会有需要将一个磁盘阵列的配置保存下来,然后在其他地方根据保存的信息进行恢复,需要依赖/etc/mdadm.conf文件进行

  1. 使用的方法是首先进行磁盘阵列信息的保存
[root@localhost ~] # mdadm -D --scan >> /etc/mdadm.conf
[root@localhost ~] # cat /etc/mdadm.conf
ARRAY  /dev/md0  metadata=1.2 name=localhost.localdomain:0 UUID=82254c47:09
  1. 此时就可将原来的磁盘阵列停止
[root@localhost ~] # mdadm -S /dev/md0
mdadm: stopped  /dev/md0
[root@localhost ~] #
  1. 然后再查看磁盘阵列的信息,发现已经没有磁盘阵列存在了
[root@localhost ~] # cat /proc/mdstat 
Personalities : [raid0] [raid6] [raid5] [raid4] 
unused devices: <none>
[root@localhost ~] #
  1. 接下来就可以使用mdadm -A /dev/md0 命令来快速恢复磁盘阵列
[root@localhost ~] # mdadm -A /dev/md0
mdadm:  /dev/md0  has been started with 3 drives.
[root@localhost ~] #
  1. 再次查看磁盘阵列的信息,发现刚才停止的磁盘阵列又回来了
[root@localhost ~] # cat /proc/mdstat 
Personalities : [raid0] [raid6] [raid5] [raid4] 
md0 : active raid5 sdb1[0] sdb3[3] sdb2[4]
       4190208 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3 /3 ] [UUU]
       
unused devices: <none>
[root@localhost ~] #

1.4 多种raid对比

在这里插入图片描述

2. 网卡的bound技术

网卡bond,即网卡绑定,也称作网卡捆绑。网卡绑定有多种称谓:Port Trunking, Channel Bonding, Link Aggregation, NIC teaming等等,其实说的是一回事。就是将两个或者更多的物理网卡绑定成一个虚拟网卡。通过绑定可以达到链路冗余、带宽倍增、负载均衡等目的。是生产场景中提高性能和可靠性的一种常用技术。
Linux内置了网卡绑定的驱动程序,可以将多个物理网卡分别捆绑成多个不同的逻辑网卡(例如把eth0、eth1捆绑成bond0,把eth2、eth3捆绑成bond1)。对于每一个bond接口来说,可以分别定义不同的绑定模式和链路监视选项。

2.1 bond的模式

对应于不同的负载均衡和容错特性需求,Linux网卡bond的模式共有bond0-bond6共7种。

2.1.1 mode=0(balance-rr)

表示负载分担round-robin,并且是轮询的方式,比如第一个包走eth0,第二个包走eth1,直到数据包发送完毕。

优点:可用带宽提高一倍
缺点:需要接入交换机做端口聚合,否则可能无法使用

2.1.2 mode=1(active-backup)

表示主备模式,即同一时间时只有1块网卡在工作。

优点:冗余性高
缺点:链路利用率低,两块网卡只有1块在工作,N块网卡绑定时利用率是1/N

2.1.3 mode=2(balance-xor)(平衡策略)

表示使用MAC地址的XOR Hash负载分担,网络上特定的通信双方会始终经由某一个网卡的链路通信,和交换机的聚合强制不协商方式配合。(需要xmit_hash_policy[1],需要交换机配置port channel)

特点:基于指定的传输HASH策略传输数据包。缺省的策略是:(源MAC地址 XOR 目标MAC地址) % slave数量。其他的传输策略可以通过xmit_hash_policy选项指定,此模式提供负载平衡和容错能力

2.1.4 mode=3(broadcast)(广播策略)

表示所有包从所有绑定的网络接口发出,不考虑均衡流量的分担,只有冗余机制,但过于浪费资源。此模式适用于金融行业,因为他们需要高可靠性的网络,不允许出现任何问题。需要和交换机的聚合强制不协商方式配合。

特点:在每个slave接口上传输每个数据包,此模式提供了容错能力

2.1.5 mode=4(802.3ad)(IEEE 802.3ad 动态链接聚合)

表示支持802.3ad协议,和交换机的聚合LACP方式配合(需要xmit_hash_policy).标准要求所有设备在聚合操作时,要在同样的速率和双工模式。

特点:创建一个聚合组,它们共享同样的速率和双工设定。根据802.3ad规范将多个slave工作在同一个激活的聚合体下。外出流量的slave选举是基于传输hash策略,该策略可以通过xmit_hash_policy选项从缺省的XOR策略改变到其他策略。需要注意的是,并不是所有的传输策略都是802.3ad适应的,尤其考虑到在802.3ad标准43.2.4章节提及的包乱序问题。不同的实现可能会有不同的适应性。
必要条件:
条件1:ethtool支持获取每个slave的速率和双工设定
条件2:switch(交换机)支持IEEE802.3ad Dynamic link aggregation
条件3:大多数switch(交换机)需要经过特定配置才能支持802.3ad模式

2.1.6 mode=5(balance-tlb)(适配器传输负载均衡)

是根据每个slave的负载情况选择slave进行发送,接收时使用当前轮到的slave。该模式要求slave接口的网络设备驱动有某种ethtool支持;而且ARP监控不可用。

特点:不需要任何特别的switch(交换机)支持的通道bonding。在每个slave上根据当前的负载(根据速度计算)分配外出流量。如果正在接受数据的slave出故障了,另一个slave接管失败的slave的MAC地址。
必要条件:
ethtool支持获取每个slave的速率
mode=6(balance-alb)(适配器适应性负载均衡)
在5的tlb基础上增加了rlb(接收负载均衡receiveload balance).不需要任何switch(交换机)的支持。接收负载均衡是通过ARP协商实现的.

2.2 常用命令

2.2.1 添加bond配置

  1. 创建ifcfg-bond0
    创建ifcfg-bond0文件,配置IP地址、子网掩码、网关等参数。
# cat /etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0 
IPADDR=192.168.1.12 
NETMASK=255.255.255.0 
GATEWAY=192.168.1.1 
USERCTL=no 
BOOTPROTO=none 
ONBOOT=yes
  1. 修改网卡配置文件ifcfg-eth*(以三个网卡绑定为例)
    修改eth0、eth1、eth2的配置文件,注释或删除IP地址、掩码、网关和MAC地址的配置,添加关于MASTER和SLAVE的设置
# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0 
BOOTPROTO=none 
ONBOOT=yes 
# Settings for Bond 
MASTER=bond0 
SLAVE=yes

# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1 
BOOTPROTO=none  
ONBOOT=yes 
USERCTL=no 
# Settings for bonding 
MASTER=bond0 
SLAVE=yes

# cat /etc/sysconfig/network-scripts/ifcfg-eth2
DEVICE=eth2 
BOOTPROTO=none 
ONBOOT=yes 
MASTER=bond0 
SLAVE=yes
  1. 确定选用何种bonding模式
    根据实际需求,选择合适的bonding模式,为bond0设置bonding kernel module。
    在/etc/modprobe.conf中添加以下内容
cat /etc/modprobe.conf
# bonding commands 
alias bond0 bonding 
options bond0 mode=1 miimon=200

options中

  • miimon:监视网络链接的频度,单位是毫秒,我们设置的是200毫秒。为0则不检测
  • max_bonds:配置的bond口个数
  • mode:bond模式,主要有0-6共7种,在一般的实际应用中,0和1用的比较多
  1. 激活bonding驱动
# modprobe bonding

确认模块是否加载成功

#lsmod | grep bonding 
  1. 重启网络,并确认一下bond0的状态

重启网络(或重启主机)

# service network restart

查看bond0的状态

# cat /proc/net/bonding/bond0 
Ethernet Channel Bonding Driver
Bonding Mode: adaptive load balancing 
Primary Slave: None 
Currently Active Slave: eth2 
MII Status: up 
MII Polling Interval (ms): 100 
Up Delay (ms): 0 
Down Delay (ms): 0
Slave Interface: eth2 
MII Status: up 
Link Failure Count: 0 
Permanent HW addr: 00:13:72:80: 62:f0

另外还可以使用ifconfig -a | grep HWaddr查看bond0接口是否处于活动状态,以及各网卡MAC地址情况

# ifconfig | grep HWaddr  
bond0 Link encap:Ethernet HWaddr 00:16:36:1B:BB:74  
eth0 Link encap:Ethernet HWaddr 00:16:36:1B:BB:74  
eth1 Link encap:Ethernet HWaddr 00:16:36:1B:BB:74 
eth2 Link encap:Ethernet HWaddr 00:16:36:1B:BB:74 

从上面的确认信息中,我们可以看到3个重要信息:
1.现在的bonding模式是active-backup
2.现在Active状态的网口是eth2
3.bond0,eth0、eth1、的物理地址和处于active状态下的eth2的物理地址相同,这样是为了避免上位交换机发生混乱。

  1. 测试验证
    可以ping一个远程地址,然后断开Active状态的eth2口网线,验证主备模式是否能正常切换,业务是否受到影响。

2.2.2 ifenslave调整网卡

将网口添加到bond中:ifenslave bond eth0 eth1【bond要先up】
将bond中删除网口:ifenslave -d bond eth0
bond中网口主备倒换:ifenslave -c bond eth1

2.2.3 多个bond口如何处理

有如下两种方式

  1. 多个bond口的模式就只能设成相同的了:
alias bond0 bonding  
alias bond1 bonding  
options bonding max_bonds=2 miimon=200 mode=1 
  1. 不同的bond口的mode可以设成不一样:
alias bond0 bonding  
options bond0 miimon=100 mode=1  
install bond1 /sbin/modprobe bonding -o bond1 miimon=200 mode=0 

按照上面这2种设置方法,现在如果是要设置3个,4个,甚至更多的bond口,可是可以的。

3. 参考文档

暂无

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>