关于java:一文参透分布式存储系统Ceph的架构设计集群搭建手把手

2次阅读

共计 11708 个字符,预计需要花费 30 分钟才能阅读完成。

1. Ceph 概述

1.1 背景

Ceph 是一个去中心化的分布式存储系统,提供较好的性能、可靠性和可扩展性。Ceph 我的项目最早起源于 Sage 就读博士期间的工作(最早的成绩于 2004 年发表),并随后奉献给开源社区,遵循 LGPL 协定(LESSER GENERAL PUBLIC LICENSE 的简写,中文译为“较宽松公共许可证”)。在通过了数年的倒退之后,目前已失去泛滥云计算厂商(OpenStack、CloudStack、OpenNebula、Hadoop)的反对并被广泛应用。

1.2 介绍

Ceph 是一个牢靠、主动重平衡、主动复原的分布式存储系统,依据场景划分能够将 Ceph 分为三大块,别离是对象存储、块设施和文件系统服务。

Ceph 的次要长处是分布式存储,在存储每一个数据时,都会通过计算得出该数据存储的地位,尽量将数据分布平衡,不存在传统的单点故障的问题,能够程度扩大。

Ceph 存储集群至多须要一个 Ceph Monitor 和两个 OSD 守护过程。而运行 Ceph 文件系统客户端时,则必须要有元数据服务器(Metadata Server)。

1.3 特点

Ceph 适宜跨集群的小文件存储,领有以下特点:

  • 高性能

    Client 和 Server 间接通信,不须要代理和转发;

    Client 不须要负责正本的复制,有 Primary 主节点负责,这样能够无效升高 clien 网络的耗费;

    采纳 CRUSH 算法,数据分布平衡,并行度高,反对上千个存储节点,反对 TB 及 PB 级数据。

  • 高可用性

    数据多正本,反对故障域分隔,数据强一致性;

    没有单点故障,较好的容错性,无效撑持各种故障场景;

    反对所有故障的检测和主动复原,能够做到自动化治理;

    反对并行复原,可能极大的升高数据恢复工夫,进步数据的可靠性。

  • 高扩展性

    高度并行化设计,没有单个核心管制组件,所有负载都能动静的划分到各个服务器上。

    去中心化、灵便、随节点减少线性增长。

  • 场景丰盛

    反对三种存储接口类型: 块存储、文件存储、对象存储。同时反对自定义接口,C++ 为底层实现,兼容多种语言。

    • 块存储 :将磁盘空间映射给主机应用,实用 docker 容器、虚拟机磁盘存储调配;日志存储,文件存储。
    • 文件存储 :解决块存储无奈共享问题,在服务器架设 FTP 和 NFS 服务器,实用目录构造的存储、日志存储等。
    • 对象存储 :大容量硬盘,装置存储管理软件,对外提供读写访问能力,具备块存储的高速读写能力,也具备文件存储共享的个性;实用图片存储或视频存储。

1.4 分布式存储系统横纵比照

比照阐明 TFS FASTDFS MooseFS GlusterFS CEPH
开发语言 C++ C C C C++
数据存储形式 文件 /Trunk 文件 / 块 对象 / 文件 / 块
在线扩容 反对 反对 反对 反对 反对
冗余备份 反对 反对 反对 反对 反对
单点故障 存在 不存在 存在 不存在 不存在
易用性 装置简单,官网文档少 安装简单,社区绝对沉闷 安装简单,官网文档多 安装简单,官网文档专业化 安装简单,官网文档专业化
实用场景 跨集群的小文件 单集群的中小文件 单集群的大中文件 跨集群云存储 单集群的大中小文件

2. Ceph 架构设计

2.1 Ceph 整体设计

  • 根底存储系统 RADOS

    Reliable, Autonomic,Distributed Object Store,即牢靠的、自动化的、分布式的对象存储

    这就是一个残缺的对象存储系统,所有存储在 Ceph 零碎中的用户数据事实上最终都是由这一层来存储的。而 Ceph 的高牢靠、高可扩大、高性能、高自动化等等个性实质上也是由这一层所提供的。

  • 根底库 librados

    这层的性能是对 RADOS 进行形象和封装,并向下层提供 API,以便间接基于 RADOS(而不是整个 Ceph)进行利用开发。特地要留神的是,RADOS 是一个对象存储系统,因而,librados 实现的 API 也只是针对对象存储性能的。RADOS 采纳 C ++ 开发,所提供的原生 librados API 包含 C 和 C ++ 两种。

  • 高层利用接口

    这层包含了三个局部:RADOS GW(RADOS Gateway)、RBD(Reliable Block Device)和 Ceph FS(Ceph File System),其作用是在 librados 库的根底上提供抽象层次更高、更便于利用或客户端应用的下层接口。其中,RADOS GW 是一个提供与 Amazon S3 和 Swift 兼容的 RESTful API 的 gateway,以供相应的对象存储利用开发应用。RADOS GW 提供的 API 抽象层次更高,但性能则不如 librados 弱小。

  • 应用层

    这层是不同场景下对于 Ceph 各个利用接口的各种利用形式,例如基于 librados 间接开发的对象存储利用,基于 RADOS GW 开发的对象存储利用,基于 RBD 实现的云硬盘等等。librados 和 RADOS GW 的区别在于,librados 提供的是本地 API,而 RADOS GW 提供的则是 RESTfulAPI。

    因为 Swift 和 S3 反对的 API 性能近似,这里以 Swift 举例说明。Swift 提供的 API 性能次要包含:

    • 用户治理操作:用户认证、获取账户信息、列出容器列表等;
    • 容器治理操作:创立 / 删除容器、读取容器信息、列出容器内对象列表等;
    • 对象治理操作:对象的写入、读取、复制、更新、删除、拜访许可设置、元数据读取或更新等。

2.2 逻辑架构

2.3 Ceph 专业术语

  • OSD: Ceph 的对象存储设备,OSD 守护过程的性能是存储数据,解决数据的复制、复原、回填、再平衡,并通过查看其余 OSD 守护过程的心跳来向 Ceph Monitors 提供一些监控信息。
  • Monitors: Ceph 监视器,Monitor 保护着展现集群状态的各种图表,包含监视器图、OSD 图、归置组(PG)图、和 CRUSH 图。
  • PG:Ceph 归置组,每个 Object 最初都会通过 CRUSH 计算映射到某个 PG 中,一个 PG 能够蕴含多个 Object。
  • MDS: Ceph 元数据服务器(MDS),为 Ceph 文件系统存储元数据。
  • CephFS: Ceph 文件系统,CephFS 提供了一个任意大小且兼容 POSIX 的分布式文件系统。
  • RADOS: Reliable Autonomic Distributed Object Store,示意牢靠、主动、分布式的对象存储。Ceph 中的一切都是以对象模式存储,RADOS 就负责存储这些对象,RADOS 层确保数据一致性和可靠性。
  • Librados:librados 库是一种用来简化拜访 RADOS 的办法,目前反对 PHP、Python、Ruby、Java、C 和 C ++ 语言。
  • RBD:Ceph 的块设施,它对外提供块存储,能够被映射、格式化进而像其余磁盘一样挂载到服务器。
  • RGW/RADOSGW:Ceph 对象网关,它提供了一个兼容 S3 和 Swift 的 restful API 接口。

3. Ceph 集群部署配置

3.1 部署构造

虚拟机创立三台服务器,CENTOS 版本为 7.6,IP 网段 192.168.116.0/24。三台主机名称为:

  • CENTOS7-1: IP 为 192.168.116.141,既做治理节点,又做子节点。
  • CENTOS7-2: IP 为 192.168.116.142,子节点。
  • CENTOS7-3: IP 为 192.168.116.143,子节点。

3.2 系统配置

系统配置工作,三台节点顺次执行:

  1. 批改主机名称
    [root@CENTOS7-1 ~]# vi /etc/hostname

    CENTOS7-1
  2. 编辑 hosts 文件

    192.168.116.141 CENTOS7-1
    192.168.116.142 CENTOS7-2
    192.168.116.143 CENTOS7-3

    留神,这外面的主机名称要和节点名称保持一致,否则装置的时候会呈现问题

  3. 批改 yum 源
    vi /etc/yum.repos.d/ceph.repo,为防止网速过慢问题,这里采纳的是清华镜像源:

    [Ceph]
    name=Ceph packages for $basearch
    baseurl=https://mirrors.tuna.tsinghua.edu.cn/ceph/rpm-mimic/el7/x86_64/
    enabled=1
    gpgcheck=1
    type=rpm-md
    gpgkey=https://download.ceph.com/keys/release.asc
    
    [Ceph-noarch]
    name=Ceph noarch packages
    # 官网源
    #baseurl=http://download.ceph.com/rpm-mimic/el7/noarch
    # 清华源
    baseurl=https://mirrors.tuna.tsinghua.edu.cn/ceph/rpm-mimic/el7/noarch/
    enabled=1
    gpgcheck=1
    type=rpm-md
    gpgkey=https://download.ceph.com/keys/release.asc
    
    [ceph-source]
    name=Ceph source packages
    baseurl=https://mirrors.tuna.tsinghua.edu.cn/ceph/rpm-mimic/el7/SRPMS/
    enabled=1
    gpgcheck=1
    type=rpm-md
    gpgkey=https://download.ceph.com/keys/release.asc
    
    
  4. 装置 ceph 与 ceph-deploy 组件

    yum update && yum -y install ceph ceph-deploy 

    装置实现,如果执行 ceph-deploy 呈现 ImportError: No module named pkg_resources

    装置 python2-pip:yum -y install python2-pip

    yum install epel-release -y

  5. 装置 NTP 工夫同步工具

    yum install ntp ntpdate ntp-doc -y

    确保时区是正确,设置开机启动:

    systemctl enable ntpd

    并将工夫每隔 1 小时主动校准同步。编辑 vi /etc/rc.d/rc.local 追加:

    /usr/sbin/ntpdate ntp1.aliyun.com > /dev/null 2>&1; /sbin/hwclock -w

    配置定时工作, 执行 crontab -e 退出:

    0 */1 * * * ntpdate ntp1.aliyun.com > /dev/null 2>&1; /sbin/hwclock -w

3.3 免明码 SSH 登陆

  1. 官网倡议不必零碎内置用户,创立名为 ceph_user 用户,明码也设为 ceph_user:

    useradd -d /home/ceph_user -m ceph_user
    passwd ceph_user
  2. 设置 sudo 权限

    echo "ceph_user ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/ceph_user
    sudo chmod 0440 /etc/sudoers.d/ceph_user

    1、2 两个步骤顺次在三台机器上执行。

    接下来在主节点,继续执行:

  3. 生成密钥:

    切换用户:su ceph_user

    执行 ssh-keygen,始终按默认提醒点击生成 RSA 密钥信息。

  4. 散发密钥至各机器节点

    ssh-copy-id ceph_user@CENTOS7-1
    ssh-copy-id ceph_user@CENTOS7-2
    ssh-copy-id ceph_user@CENTOS7-3
  5. 批改治理节点上的 ~/.ssh/config 文件,简化 SSH 近程连贯时的输出信息:

    治理节点是会有 root 和 ceph_user 多个用户,ssh 近程连贯默认会以以后用户身份进行登陆,

    如果咱们是 root 身份进行近程连贯,还是须要输出明码,咱们想简化,该怎么解决?

    切换 root 身份,

    su root 

    批改~/.ssh/config 文件

    Host CENTOS7-1
       Hostname CENTOS7-1
       User ceph_user
    Host CENTOS7-2
       Hostname CENTOS7-2
       User ceph_user
    Host CENTOS7-3
       Hostname CENTOS7-3
       User ceph_user

    留神批改文件权限,不能采纳 777 最大权限:

    chmod 600 ~/.ssh/config

    进行 ssh 近程连贯时,Host 的主机名称是辨别大小写的,所以要留神配置文件的主机名称。

  6. 凋谢端口,非生产环境,能够间接禁用防火墙:

    systemctl stop firewalld.service
    systemctl disable firewalld.service
  7. SELINUX 设置

    SELinux 设为禁用:

    setenforce 0

    永恒失效:
    编辑 vi /etc/selinux/config 批改:

    SELINUX=disabled

3.4 集群搭建配置

采纳 root 身份进行装置

  1. 在治理节点创立集群配置目录,cd /usr/local:

    mkdir ceph-cluster
    cd ceph-cluster

    留神:此目录作为 ceph 操作命令的基准目录,会存储解决配置信息。

  2. 创立集群,蕴含三台机器节点:

    ceph-deploy new CENTOS7-1  CENTOS7-2 CENTOS7-3

    创立胜利后,会生一个配置文件。

  3. 如果接下来集群的装置配置呈现问题,能够执行以下命令革除,再重新安装:

    ceph-deploy purge CENTOS7-1  CENTOS7-2 CENTOS7-3
    ceph-deploy purgedata CENTOS7-1  CENTOS7-2 CENTOS7-3
    ceph-deploy forgetkeys

    将三台节点的 mon 信息也删除

    rm -rf /var/run/ceph/
  4. 批改配置文件,有些配置前面需用到:

    vi /usr/local/ceph-cluster/ceph.conf

    退出:

    [global]
    # 公网网络
    public network = 192.168.116.0/24
    # 设置 pool 池默认调配数量 默认正本数为 3
    osd pool default size = 2
    # 容忍更多的时钟误差
    mon clock drift allowed = 2
    mon clock drift warn backoff = 30
    # 容许删除 pool
    mon_allow_pool_delete = true
    [mgr]
    # 开启 WEB 仪表盘
    mgr modules = dashboard

    第一项为正本数,设为 2 份。

    第二项为对外 IP 拜访网段,留神依据理论 IP 批改网段。

    第三、四项为容许肯定工夫的漂移误差。

  5. 执行装置:

    ceph-deploy install  CENTOS7-1  CENTOS7-2 CENTOS7-3

    如果呈现谬误:

    ceph_deploy][ERROR] RuntimeError: Failed to execute command: ceph --version

    能够在各节点上独自进行装置:

    yum -y install ceph 

    如果没有仓库文件 ceph.repo,按下面的步骤手工创立。

  6. 初始 monitor 信息:

    ceph-deploy mon create-initial
    ## ceph-deploy --overwrite-conf mon create-initial

    执行实现后,会生成以下文件:

  7. 同步治理信息:

    下发配置文件和治理信息至各节点:

    ceph-deploy admin  CENTOS7-1  CENTOS7-2 CENTOS7-3
  8. 装置 mgr(治理守护过程),大于 12.x 版本需装置,咱们装的是最新版,需执行:

    ceph-deploy mgr create CENTOS7-1  CENTOS7-2 CENTOS7-3
  9. 装置 OSD(对象存储设备)

    留神:新版本的 OSD 没有 prepare 与 activate 命令。

    这里须要新的硬盘作为 OSD 存储设备,敞开虚拟机,减少一块硬盘,不必格式化。

    重启,fdisk -l 查看新磁盘名称:

    执行创立 OSD 命令:

    ceph-deploy osd create --data /dev/sdb CENTOS7-2

    三台节点都需别离顺次执行。

    ceph-deploy gatherkeys CENTOS7-1
  1. 验证节点:

    输出 ceph health 或 ceph - s 查看,呈现 HEALTH_OK 代表失常。

    ![file](/img/bVc1oVN)
    

通过虚拟机启动, 如果呈现谬误:

[root@CENTOS7-1 ~]# ceph -s
  cluster:
    id:     0ec99aa9-e97e-43d3-b5b9-90eb21c4abff
    health: HEALTH_WARN
            1 filesystem is degraded
            1 osds down
            1 host (1 osds) down
            Reduced data availability: 41 pgs inactive
            Degraded data redundancy: 134/268 objects degraded (50.000%), 22 pgs degraded, 87 pgs undersized
            39 slow ops, oldest one blocked for 2286 sec, daemons [osd.0,mon.CENTOS7-2,mon.CENTOS7-3] have slow ops.
            clock skew detected on mon.CENTOS7-2, mon.CENTOS7-3
 
  services:
    mon: 3 daemons, quorum CENTOS7-1,CENTOS7-2,CENTOS7-3
    mgr: centos7-1(active), standbys: centos7-3, centos7-2
    mds: fs_test-1/1/1 up  {0=centos7-1=up:replay}
    osd: 3 osds: 1 up, 2 in
 
  data:
    pools:   9 pools, 128 pgs
    objects: 134  objects, 64 KiB
    usage:   1.0 GiB used, 19 GiB / 20 GiB avail
    pgs:     32.031% pgs unknown
             134/268 objects degraded (50.000%)
             65 active+undersized
             41 unknown
             22 active+undersized+degraded

在各节点执行命令, 确保工夫同步统一:

ntpdate ntp1.aliyun.com 

3.5 装置治理后盾

  1. 开启 dashboard 模块

    ceph mgr module enable dashboard
  2. 生成签名

    ceph dashboard create-self-signed-cert
  3. 创立目录

    mkdir mgr-dashboard

    [root@CENTOS7-1 mgr-dashboard]# pwd
    /usr/local/ceph-cluster/mgr-dashboard
  4. 生成密钥对

    cd  /usr/local/ceph-cluster/mgr-dashboard
    openssl req -new -nodes -x509   -subj "/O=IT/CN=ceph-mgr-dashboard" -days 3650   -keyout dashboard.key -out dashboard.crt -extensions v3_ca
    [root@CENTOS7-1 mgr-dashboard]# ll
    total 8
    -rw-rw-r-- 1 ceph_user ceph_user 1155 Jul 14 02:26 dashboard.crt
    -rw-rw-r-- 1 ceph_user ceph_user 1704 Jul 14 02:26 dashboard.key
  5. 启动 dashboard

    ceph mgr module disable dashboard
    ceph mgr module enable dashboard
  6. 设置 IP 与 PORT

    ceph config set mgr mgr/dashboard/server_addr 192.168.116.141
    ceph config set mgr mgr/dashboard/server_port 18843
  7. 敞开 HTTPS

    ceph config set mgr mgr/dashboard/ssl false
  8. 查看服务信息

    [root@CENTOS7-1 ceph-cluster]# ceph mgr services
    {"dashboard": "http://192.168.116.142:18843/"}
  9. 设置治理用户与明码

    ceph dashboard set-login-credentials admin admin
  10. 拜访

3.6 创立 Cephfs

集群创立完后,默认没有文件系统,咱们创立一个 Cephfs 能够反对对外拜访的文件系统。

ceph-deploy --overwrite-conf mds create CENTOS7-1 CENTOS7-2 CENTOS7-3
  1. 创立两个存储池, 执行两条命令:

    ceph osd pool create cephfs_data 128
    ceph osd pool create cephfs_metadata 64

    少于 5 个 OSD 可把 pg_num 设置为 128

    OSD 数量在 5 到 10,能够设置 pg_num 为 512

    OSD 数量在 10 到 50,能够设置 pg_num 为 4096

    OSD 数量大于 50,须要计算 pg_num 的值

    通过上面命令能够列出以后创立的存储池:

    ceph osd lspools
  2. 创立 fs, 名称为 fs_test:

    ceph fs new fs_test cephfs_metadata cephfs_data
  3. 状态查看,以下信息代表失常:

    [root@CENTOS7-1 mgr-dashboard]# ceph fs ls
    name: fs_test, metadata pool: cephfs_metadata, data pools: [cephfs_data]
    [root@CENTOS7-1 mgr-dashboard]# ceph mds stat
    fs_test-1/1/1 up  {0=centos7-1=up:active}

    附:如果创立谬误,须要删除,执行:

    ceph fs rm fs_test --yes-i-really-mean-it
    ceph osd pool delete cephfs_data cephfs_data  --yes-i-really-really-mean-it

    确保在 ceph.conf 中开启以下配置:

    [mon]
    mon allow pool delete = true
  1. 采纳 fuse 挂载

    先确定 ceph-fuse 命令能执行,如果没有,则装置:

     yum -y install ceph-fuse
  2. 创立挂载目录

    mkdir -p /usr/local/cephfs_directory
  3. 挂载 cephfs

    [root@node3 ~]# ceph-fuse -k /etc/ceph/ceph.client.admin.keyring -m 192.168.116.141:6789 /usr/local/cephfs_directory
    ceph-fuse[6687]: starting ceph client
    2019-07-14 21:39:09.644181 7fa5be56e040 -1 init, newargv = 0x7fa5c940b500 newargc=9
    ceph-fuse[6687]: starting fuse
  4. 查看磁盘挂载信息

    [root@CENTOS7-1 mgr-dashboard]# df -h
    Filesystem               Size  Used Avail Use% Mounted on
    /dev/mapper/centos-root   38G  3.0G   35G   8% /
    devtmpfs                 1.9G     0  1.9G   0% /dev
    tmpfs                    1.9G     0  1.9G   0% /dev/shm
    tmpfs                    1.9G   20M  1.9G   2% /run
    tmpfs                    1.9G     0  1.9G   0% /sys/fs/cgroup
    /dev/sda1                197M  167M   31M  85% /boot
    tmpfs                    378M     0  378M   0% /run/user/0
    tmpfs                    1.9G   24K  1.9G   1% /var/lib/ceph/osd/ceph-0
    ceph-fuse                 27G     0   27G   0% /usr/local/cephfs_directory
    tmpfs                    378M     0  378M   0% /run/user/1000
    

    /usr/local/cephfs_directory 目录已胜利挂载。

3.7 客户端连贯验证 (Rados Java)

  1. 装置好 JDK、GIT 和 MAVEN。
  2. 下载 rados java 客户端源码

    git clone https://github.com/ceph/rados-java.git

    下载目录地位:

    [root@CENTOS7-1 rados-java]# pwd
    /usr/local/sources/rados-java
  3. 执行 MAVEN 装置, 疏忽测试用例:

    [root@CENTOS7-1 rados-java]# mvn install -Dmaven.test.skip=true

    生成 jar 包,rados-0.7.0.jar

    [root@CENTOS7-1 target]# ll
    总用量 104
    drwxr-xr-x 3 root root     17 8 月  11 18:32 classes
    drwxr-xr-x 2 root root     27 8 月  11 18:32 dependencies
    drwxr-xr-x 3 root root     25 8 月  11 18:32 generated-sources
    drwxr-xr-x 2 root root     28 8 月  11 18:32 maven-archiver
    drwxr-xr-x 3 root root     35 8 月  11 18:32 maven-status
    -rw-r--r-- 1 root root 105701 8 月  11 18:32 rados-0.7.0.jar
  4. 创立软链接,退出 CLASSPATH

    ln -s /usr/local/sources/rados-java/target/rados-0.7.0.jar /opt/jdk1.8.0_301/jre/lib/ext/rados-0.7.0.jar

    装置 jna

    yum -y install jna

    创立软链接

    ln -s /usr/share/java/jna.jar /opt/jdk1.8.0_301/jre/lib/ext/jna.jar

    查看

    [root@CENTOS7-1 target]# ll /opt/jdk1.8.0_301/jre/lib/ext/jna.jar
    lrwxrwxrwx 1 root root 23 8 月  11 19:00 /opt/jdk1.8.0_301/jre/lib/ext/jna.jar -> /usr/share/java/jna.jar
    [root@CENTOS7-1 target]# ll /opt/jdk1.8.0_301/jre/lib/ext/rados-0.7.0.jar
    lrwxrwxrwx 1 root root 52 8 月  11 18:59 /opt/jdk1.8.0_301/jre/lib/ext/rados-0.7.0.jar -> /usr/local/sources/rados-java/target/rados-0.7.0.jar
  5. 创立 JAVA 测试类

    CephClient 类,留神,最新版 0.6 的异样解决包地位已发生变化。

    import com.ceph.rados.Rados;
    import com.ceph.rados.exceptions.*;
    
    import java.io.File;
    
    public class CephClient {public static void main (String args[]){
    
                    try {Rados cluster = new Rados("admin");
                            System.out.println("Created cluster handle.");
    
                            File f = new File("/etc/ceph/ceph.conf");
                            cluster.confReadFile(f);
                            System.out.println("Read the configuration file.");
    
                            cluster.connect();
                            System.out.println("Connected to the cluster.");
    
                    } catch (RadosException e) {System.out.println(e.getMessage() + ":" + e.getReturnValue());
                    }
            }
    }
  6. 运行验证

    须要在 linux 环境下运行,且要在 client 节点。

    编译并运行:

    [root@CENTOS7-1 sources]# javac CephClient.java 
    [root@CENTOS7-1 sources]# java CephClient
    Created cluster handle.
    Read the configuration file.
    Connected to the cluster.

    胜利与 ceph 建设连贯。

    留神:如果 java 和 javac 版本不同,能够应用 rpm -qa |grep java 进行查找,rpm -e –nodeps jdk 进行删除,source /etc/profile 进行失效

    jdk 的位数为 64 位

本文由传智教育博学谷 – 狂野架构师教研团队公布,转载请注明出处!

如果本文对您有帮忙,欢送关注和点赞;如果您有任何倡议也可留言评论或私信,您的反对是我保持创作的能源

正文完
 0