跳到正文

· 11 分钟阅读
赵燕宁

本文讲述如何以 HwameiStor 为底座,搭建 MinIO 存储解决方案,实践验证了 MinIO 的各项基本功能和多租户隔离测试。

MinIO 简介

MinIO 是一款高性能、分布式、兼容 S3 的多云对象存储系统套件。MinIO 原生支持 Kubernetes,能够支持所有公有云、私有云及边缘计算环境。 MinIO 是 GNU AGPL v3 开源的软件定义产品,能够很好地运行在标准硬件如 X86 等设备上。

MinIO 架构

MinIO 的架构设计从一开始就是针对性能要求很高的私有云标准,在实现对象存储所需要的全部功能的基础上追求极致的性能。 MinIO 具备易用性、高效性及高性能,能够以更简单的方式提供具有弹性伸缩能力的云原生对象存储服务。

MinIO 在传统对象存储场景(如辅助存储、灾难恢复和归档)方面表现出色,同时在机器学习、大数据、私有云、混合云等方面的存储技术上也独树一帜,包括数据分析、高性能应用负载、原生云应用等。

MinIO 架构设计

MinIO 为云原生架构设计,可以作为轻量级容器运行并由外部编排服务如 Kubernetes 管理。 MinIO 整个服务包约为不到 100 MB 的静态二进制文件,即使在很高负载下也可以高效利用 CPU 和内存资源并可以在共享硬件上共同托管大量租户。 对应的架构图如下:

架构图

MinIO 用作云原生应用程序的主要存储,与传统对象存储相比,云原生应用程序需要更高的吞吐量和更低的延迟,而这些都是 MinIO 能够达成的性能指标,读/写速度高达 183 GB/秒和 171 GB/秒。

MinIO 极致的高性能离不开底层存储基础平台。本地存储在众多的存储协议中具有最高的读写性能无疑能为 MinIO 提供性能保障。 HwameiStor 正是满足云原生时代要求的储存系统。它具有高性能、高可用、自动化、低成本、快速部署等优点,可以替代昂贵的传统 SAN 存储。

MinIO 可以在带有本地驱动器(JBOD/JBOF)的标准服务器上运行。 集群为完全对称的体系架构,即所有服务器的功能均相同,没有名称节点或元数据服务器。

MinIO 将数据和元数据作为对象一起写入从而无需使用元数据数据库。 MinIO 以内联、严格一致的操作执行所有功能,包括擦除代码、位 rotrot 检查、加密等。

每个 MinIO 集群都是分布式 MinIO 服务器的集合,每个节点一个进程。 MinIO 作为单个进程在用户空间中运行,并使用轻量级的协同例程来实现高并发。 将驱动器分组到擦除集(默认情况下,每组 16 个驱动器),然后使用确定性哈希算法将对象放置在这些擦除集上。

MinIO 专为大规模、多数据中心云存储服务而设计。 每个租户都运行自己的 MinIO 集群,该集群与其他租户完全隔离,从而使租户能够免受升级、更新和安全事件的任何干扰。 每个租户通过联合跨地理区域的集群来独立扩展。

node-distribution-setup

以 HwameiStor 为底座搭建 MinIO 的优势

以 HwameiStor 为底座搭建 MinIO 存储方案,构建智、稳、敏全面增强本地存储,具备以下优势。

  • 自动化运维管理

    可以自动发现、识别、管理、分配磁盘。 根据亲和性,智能调度应用和数据。自动监测磁盘状态,并及时预警。

  • 高可用的数据

    使用跨节点副本同步数据, 实现高可用。发生问题时,会自动将应用调度到高可用数据节点上,保证应用的连续性。

  • 丰富的数据卷类型

    聚合 HDD、SSD、NVMe 类型的磁盘,提供非低延时,高吞吐的数据服务。

  • 灵活动态的线性扩展

    可以根据集群规模大小进行动态的扩容,灵活满足应用的数据持久化需求。

  • 丰富的应用场景,广泛适配企业需求,适配高可用架构中间件

    类似 Kafka、ElasticSearch、Redis 等这类中间件自身具备高可用架构,同时对数据的 IO 访问有很高要求。 HwameiStor 提供的基于 LVM 的单副本本地数据卷,可以很好地满足它们的要求。

  • 为应用提供高可用数据卷

    MySQL 等 OLTP 数据库要求底层存储提供高可用的数据存储,当发生问题时可快速恢复数据,同时也要求保证高性能的数据访问。 HwameiStor 提供的双副本的高可用数据卷,可以很好地满足此类需求。

  • 自动化运维传统存储软件

    MinIO、Ceph 等存储软件,需要使用 Kubernetes 节点上的磁盘,可以采用 PVC/PV 的方式, 通过 CSI 驱动自动化地使用 HwameiStor 的单副本本地卷,快速响应业务系统提出的部署、扩容、迁移等需求,实现基于 Kubernetes 的自动化运维。

测试环境

按照以下步骤依次部署 Kubernetes 集群、HwameiStor 本地存储和 MinIO。

部署 Kubernetes 集群

本次测试使用了三台虚拟机节点部署了 Kubernetes 集群:1 Master + 2 Worker 节点,kubelet 版本为 1.22.0。

k8s-cluster

部署 HwameiStor 本地存储

在 Kubernetes 上部署 HwameiStor 本地存储。

查看 HwameiStor 本地存储

两台 Worker 节点各配置了五块磁盘(SDB、SDC、SDD、SDE、SDF)用于 HwameiStor 本地磁盘管理。

lsblk

lsblk

查看 local storage node 状态。

get-lsn

创建了 storagClass。

get-sc

分布式多租户源码部署安装(minio operator)

本节说明如何部署 minio operator,如何创建租户,如何配置 HwameiStor 本地卷。

部署 minio operator

参照以下步骤部署 minio operator。

  1. 复制 minio operator 仓库到本地。

    git clone <https://github.com/minio/operator.git>

    helm-repo-list

    ls-operator

  2. 进入 helm operator 目录:/root/operator/helm/operator

    ls-pwd

  3. 部署 minio-operator 实例。

    helm install minio-operator \
    --namespace minio-operator \
    --create-namespace \
    --generate-name .
    --set persistence.storageClass=local-storage-hdd-lvm .
  4. 检查 minio-operator 资源运行情况。

    get-all

创建租户

参照以下步骤创建一个租户。

  1. 进入 /root/operator/examples/kustomization/base 目录。如下修改 tenant.yaml。

    git-diff-yaml

  2. 进入 /root/operator/helm/tenant/ 目录。如下修改 values.yaml 文件。

    git-diff-values.yaml

  3. 进入 /root/operator/examples/kustomization/tenant-lite 目录。如下修改 kustomization.yaml 文件。

    git-diff-kustomization-yaml

  4. 如下修改 tenant.yaml 文件。

    git-diff-tenant-yaml02

  5. 如下修改 tenantNamePatch.yaml 文件。

    git-diff-tenant-name-patch-yaml

  6. 创建租户:

    kubectl apply –k . 
  7. 检查租户 minio-t1 资源状态:

    kubectl-get-all-nminio-tenant

  8. 如要创建一个新的租户可以在 /root/operator/examples/kustomization 目录下建一个新的 tenant 目录(本案例为 tenant-lite-2)并对相应文件做对应修改。

    pwd-ls-ls

  9. 执行 kubectl apply –k . 创建新的租户 minio-t2

    kubectl-get-all-nminio

配置 HwameiStor 本地卷

依次运行以下命令来配置本地卷。

kubectl get statefulset.apps/minio-t1-pool-0 -nminio-tenant -oyaml

local-storage-hdd-lvm

kubectl get pvc –A

kubectl-get-pvc

kubectl get pvc export-minio6-0 -nminio-6 -oyaml

kubectl-get-pvc-export-oyaml

kubectl get pv

kubectl-get-pv

kubectl get pvc data0-minio-t1-pool-0-0 -nminio-tenant -oyaml

kubectl-get-pvc-oyaml

kubectl get lv

kubectl-get-lv

kubect get lvr

kubectl-get-lvr

HwameiStor 与 MinIo 测试验证

完成上述配置之后,执行了基本功能测试和多租户隔离测试。

基本功能测试

基本功能测试的步骤如下。

  1. 从浏览器登录 minio console:10.6.163.52:30401/login

    minio-opeartor-console-login

  2. 通过 kubectl minio proxy -n minio-operator 获取 JWT。

    minio-opeartor-console-login

  3. 浏览及管理创建的租户信息。

    tenant01

    tenant02

    tenant03

    tenant04

    tenant05

    tenant06

  4. 登录 minio-t1 租户(用户名 minio,密码 minio123)。

    login-minio

    login-minio

  5. 浏览 bucket bk-1。

    view-bucket-1

    view-bucket-1

    view-bucket-1

  6. 创建新的 bucket bk-1-1。

    create-bucket-1-1

    create-bucket-1-1

    create-bucket-1-1

  7. 创建 path path-1-2。

    create-path-1-2

    create-path-1-2

  8. 上传文件成功:

    upload-file

    upload-file

    upload-file

  9. 上传文件夹成功:

    upload-folder

    upload-folder

    upload-folder

    upload-folder

  10. 创建只读用户:

    create-user

    create-user

多租户隔离测试

执行以下步骤进行多租户隔离测试。

  1. 登录 minio-t2 租户。

    login-t2

    login-t2

  2. 此时只能看到 minio-t2 内容,minio-t1 的内容被屏蔽。

    only-t2

  3. 创建 bucket。

    create-bucket

    create-bucket

  4. 创建 path。

    create-path

    create-path

  5. 上传文件。

    upload-file

    upload-file

  6. 创建用户。

    create-user

    create-user

    create-user

    create-user

    create-user

  7. 配置用户 policy。

    user-policy

    user-policy

  8. 删除 bucket。

    delete-bucket

    delete-bucket

    delete-bucket

    delete-bucket

    delete-bucket

    delete-bucket

结论

本次测试是在 Kubernetes 1.22 平台上部署了 MinIO 分布式对象存储并对接 HwameiStor 本地存储。在此环境中完成了基本能力测试、系统安全测试及运维管理测试。

全部测试成功通过,证实了 HwameiStor 能够完美适配 MinIO 存储方案。

· 16 分钟阅读
吴慧

直播回顾

云原生产业的快速发展,为行业应用的实现带来了更多可能性,但也面临更多的挑战。存储是应用运行的基石,随着云原生技术的广泛应用,越来越多的有状态应用被搬上容器平台,有状态应用已成为了存储的主要对象,存储也成为应用容器化过程中的主要难点。在云原生时代下,对存储系统提出了哪些新的要求?云原生存储面临哪些新机遇和新挑战?目前有哪些热门的云原生存储解决方案?

在 6 月 20 日的论道原生直播间,我们携手鹏云网络,分享了三个方面内容,云原生本地存储、 Kubernetes (K8s) 场景下云原生存储解决方案,以及 “云原生时代需要什么样的存储系统” 的圆桌讨论,共话云原生存储未来。

云原生本地存储 HwameiStor

云原生存储作为云原生堆栈中容器化操作的底层架构之一,将底层存储服务暴露给容器和微服务,可以聚合来自不同介质的存储资源,通过提供持久卷使有状态的工作负载能够在容器内运行。CNCF 官方对于云原生存储形态的定义,一般包括三点,第一是运行在 K8s 上,即其本身是容器形态。第二是使用 K8s 对象类,主要是自定义资源 Custom Resource Define (CRD)。第三是最重要的一点,必须使用容器存储接口 Container Storage Interface (CSI) 。HwameiStor 正是基于以上定义开发的,一个端到端的云原生本地存储系统。

HwameiStor 系统架构

HwameiStor 最底层是一个本地磁盘管理器 Local Disk Manager (LDM),管理器将各种存储介质 (比如 HDD、SSD 和 NVMe 磁盘) 形成本地存储资源池进行统一管理,管理和接入完全自动。部署完 HwameiStor 后,即可根据介质的不同,分配至不同的资源池。资源池之上采用逻辑卷管理 Logical Volume Manager (LVM) 进行管理,使用 CSI 架构提供分布式的本地数据卷服务,为有状态的云原生应用或组件,提供数据持久化能力。

HwameiStor 是专门为云原生需求设计的存储系统,有高可用、自动化、低成本、快速部署、高性能等优点,可以替代昂贵的传统存储区域网络 Storage Area Network (SAN)。它有三个核心组件:

  • 本地盘管理 (LDM),使用 CRD 定义及管理本地数据盘,通过 LDM,在 K8s内部可明确获取到本地磁盘的属性、大小等信息。

  • 本地存储 (LS),在实现本地盘管理之后,通过 LVM 卷组管理,将逻辑卷 LV 分配给物理卷 PV 。

  • 调度器 (Scheduler),把容器调度到本地有数据的节点上。

HwameiStor 的核心在于自定义资源 CRD 的定义及实现,在 K8s 已有 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 对象类之上,Hwameistor 定义了更丰富的对象类把 PV/PVC 和本地数据盘关联起来。

HwameiStor 有四点特性:

  • 自动化运维管理,自动发现、识别、管理、分配磁盘,根据亲和性智能调度应用和数据,还可自动监测磁盘状态并及时预警。
  • 高可用的数据支持,HwameiStor 使用跨节点副本同步数据,实现高可用,发生问题时,它会自动将应用调度到高可用数据节点上,保证应用的连续性。
  • 丰富的数据卷类型,HwameiStor 聚合 HDD、SSD、NVMe 类型的磁盘,提供低延时,高吞吐的数据服务。
  • 灵活动态的线性扩展,HwameiStor 根据集群规模大小进行动态的扩容,灵活满足应用的数据持久化需求。

HwameiStor 的应用场景主要包括以下三类:

  • 适配高可用架构中间件 Kafka、ElasticSearch、Redis 等,这类中间件应用自身具备高可用架构,同时对数据的 IO 访问有很高要求。HwameiStor 提供的基于 LVM 的单副本本地数据卷,可以很好地满足它们的要求。

  • 为应用提供高可用数据卷 MySQL 等 OLTP 数据库,要求底层存储提供高可用的数据存储,当发生问题时可快速恢复数据,同时,也要求保证高性能的数据访问。HwameiStor 提供的双副本的高可用数据卷,可以很好地满足此类需求。

  • 自动化运维传统存储软件 MinIO、Ceph 等存储软件,需要使用 K8s 节点上的磁盘,可以采用 PVC/PV 的方式,通过 CSI 驱动自动化地使用 HwameiStor 的单副本本地卷,快速响应业务系统提出的部署、扩容、迁移等需求,实现基于 K8s 的自动化运维。

K8s 场景下的云原生存储解决方案————ZettaStor HASP

根据云原生基金会 (CNCF) 2020 年度报告,有状态应用已经成为了容器应用的主流,占比达到了 55%,其中有 29% 将存储列为了采用容器技术的主要挑战,而现有云原生环境面临的一个存储难题,就是性能与可用性难以兼顾,单纯使用一种存储,无法满足所有需求。因此在有状态应用的实际落地过程中,数据存储技术是关键。

存储方案对比

ZettaStor HASP 是一个云原生高性能数据聚合存储平台,它是一个高性能的用户态文件系统,具备跨异构存储多副本冗余保护的能力。相比传统的分布式存储系统而言,数据副本可以在不同类型的存储系统之间流动。除此之外,还可实现存储资源统一灵活编排,并与容器平台紧密集成。

以三个场景为例:

  • 对于 Kafka、Redis、MongoDB、HDFS 等性能要求高,且自身具备数据冗余机制的分布式应用,ZettaStor HASP 拥有更高的数据访问性能,可以实现存储资源动态分配及精细化管理。

  • MySQL、PostgreSQL 等自身不提供数据冗余机制,只能依赖外部存储,舍弃本地存储的高性能,ZettaStor HASP 可通过跨节点冗余保护,实现数据的高可用,同时兼具本地存储的高性能。

  • 对于关键业务而言,需要防范两节点同时故障的风险,而 ZettaStor HASP 跨本地及外部存储的副本冗余保护,可保障关键业务运行无忧。

ZettaStor HASP 系统架构

ZettaStor HASP 分为三层架构,最上层是高性能的分布式文件系统,也是 HASP 的核心,这个用户态的文件系统是完全自主研发的,全面兼容 POSIX 标准,在用户态与内核态之间实现零数据拷贝,可彻底发挥 NVMe SSD/SCM/PM 等高速介质的性能。第二层是数据服务层,除了在不同节点的本地存储之间、本地存储与外部存储之间、异构外部存储之间提供服务,还可针对单副本和多副本、强一致性和弱一致性分别提供存储方案。第三层是存储管理层,负责对不同的存储设备进行交互,通过统一的数据格式打破设备壁垒及数据孤岛,让数据及业务能够跨异构设备自由流动。除此之外,该系统还可通过 CSI 接口进行存储设备的调度。

ZettaStor HASP 是一个与容器平台紧密结合的分布式存储平台,可进行超融合部署和 CSI 集成,具备节点亲和性,可对用户 Pod 运行状态进行感知,使得存储行为更加适配。

圆桌讨论

Q1: 什么是云原生存储?

郑泓超:狭义的云原生存储需要满足三点,第一,与 CSI 接口实现良好的对接,满足 CSI 规范;其次,需要以容器的形式部署在 K8s 上;第三,存储系统内部的信息,也需要通过 CRD 产生新的对象类,并最终存储在 K8s 中。

冯钦:云原生上的存储是满足多种特性、多种需求的一个解决方案,除了提供统一的存储平台,应对不同的存储应用,提供不同的存储特性,实现统一纳管之外,还需要对接 CSI 接口,并打通存储与 K8s 之间的交流。

牛乐川:现在应用最广的云原生存储,还是在云存储和或者分布式存储的基础上实现云原生化。同时,也有厂商在传统存储具备的特殊能力方面进行一些延伸的尝试。

Q2: 云原生存储应该如何支持云原生应用?

冯钦:主要分为两个方面,第一,云原生存储需要支持云原生应用的特性,特性决定了应用对于存储的要求。第二,需要满足 CSI 的要求,以支持云原生特殊的需求。

牛乐川:从性能角度来看,云原生存储需要全方位满足 CSI 架构的要求,以应对多样化的云原生场景。为了给云原生应用提供良好的底层支持和响应保障,云原生存储需要实现高效运维。根据现实情况,云原生存储在成本、迁移性和技术支持方面也有考量。和云原生应用一样,云原生存储需要 “弹性”,运算方面应当具备弹性扩展能力,数据方面也需要实现扩容缩容,以及冷热数据之间的转换。除此之外,云原生存储应当具备一个开放的生态。

Q3:云原生存储和传统存储之间的异同点及优劣势?

郑泓超:云原生存储部署之后是聚合形态,而传统存储接入 K8s 一般是分离形态。云原生存储因为运行在 K8s 上,有利于开发微服务,而传统存储往往需要开发者进行存储的 API 扩展。但是,聚合形态也在一定程度上,导致 K8s 的问题容易蔓延到存储当中,给运维带来困难。除此之外,云原生存储还存在网络共享和硬盘负载方面的问题。

冯钦:外部存储中,存储节点和计算节点之间的影响很低,后端存储一般为分布式存储,安全性和可用性相对较高。但在云原生场景下,单一使用外部存储存在一定的劣势,性能上会增加网络的消耗,同时还存在额外成本增加以及与 K8s 的联动不足的问题。

Q4: 云原生存储中应该如何赋能传统存储?

牛乐川:这是一个非常迫切的需求,对于 K8s 原生的能力,比如删除、创建、扩容的能力,主要是通过 CRD 进行实现,社区也在积极部署。同时,传统存储中积攒的一些能力,尚未在云原生存储体系中得到体现,比如定时任务、可观测性等。如何在平台侧更好地让云原生赋能传统存储,充分发挥双方的优势能力,将云原生存储发展成熟,还有很多需要努力的空间,我们团队也正在进行这方面的研发。

郑泓超:再总结一个点,在常规的做法里,K8s 对接传统存储,需要完成的是 CSI 驱动集合,但这只局限于表面,CSI 定义了一部分存储的操作流程,但更多还只是一个接口。所以,CSI 社区是否应该对常规存储的一些功能 (例如定时备份、高可用等) 用 CRD 进行定义?而厂商能否做一部分工作,把一些高级的、特殊的流程用 CRD 进行定义?从而使得 K8s 能在存储领域得到更广泛的应用,是值得我们去思考和实践的。

· 20 分钟阅读
赵燕宁
要海峰

本次测试环境为 Kubernetes 1.22,对接 HwameiStor 本地存储后,成功部署 TiDB 1.3,随后执行数据库 SQL 基本能力测试、系统安全测试及运维管理测试。

全部测试成功通过,证实 HwameiStor 能够完美支撑 TiDB 这类高可用、强一致要求较高、数据规模较大的分布式数据库应用场景。

TiDB 简介

TiDB 是一款同时支持在线事务处理 (OLTP) 与在线分析处理 (OATP) 的融合型分布式数据库产品,具备水平扩缩容、金融级高可用、实时 HTAP(即同时支持 OLTP 和 OATP)、云原生的分布式数据库,兼容 MySQL 5.7 协议和 MySQL 生态等重要特性。TiDB 的目标是为用户提供一站式的 OLTP、OLAP、HTAP 解决方案,适合高可用、强一致要求较高、数据规模较大等各种应用场景。

TiDB 整体架构

TiDB 分布式数据库将整体架构拆分成了多个模块,各模块之间互相通信,组成完整的 TiDB 系统。对应的架构图如下:

TiDB 架构图

  • TiDB Server

    SQL 层对外暴露 MySQL 协议的连接端点,负责接受客户端的连接,执行 SQL 解析和优化,最终生成分布式执行计划。TiDB 层本身是无状态的,实践中可以启动多个 TiDB 实例,通过负载均衡组件(如 LVS、HAProxy 或 F5)对外提供统一的接入地址,客户端的连接可以均匀地分摊在多个 TiDB 实例上以达到负载均衡的效果。TiDB Server 本身并不存储数据,只是解析 SQL,将实际的数据读取请求转发给底层的存储节点 TiKV(或 TiFlash)。

  • PD (Placement Driver) Server

    整个 TiDB 集群的元信息管理模块,负责存储每个 TiKV 节点实时的数据分布情况和集群的整体拓扑结构,提供 TiDB Dashboard 管控界面,并为分布式事务分配事务 ID。PD 不仅存储元信息,同时还会根据 TiKV 节点实时上报的数据分布状态,下发数据调度命令给具体的 TiKV 节点,可以说是整个集群的“大脑”。此外,PD 本身也是由至少 3 个节点构成,拥有高可用的能力。建议部署奇数个 PD 节点。

  • 存储节点

    • TiKV Server:负责存储数据,从外部看 TiKV 是一个分布式的提供事务的 Key-Value 存储引擎。存储数据的基本单位是 Region,每个 Region 负责存储一个 Key Range(从 StartKey 到 EndKey 的左闭右开区间)的数据,每个 TiKV 节点会负责多个 Region。TiKV 的 API 在 KV 键值对层面提供对分布式事务的原生支持,默认提供了 SI (Snapshot Isolation) 的隔离级别,这也是 TiDB 在 SQL 层面支持分布式事务的核心。TiDB 的 SQL 层做完 SQL 解析后,会将 SQL 的执行计划转换为对 TiKV API 的实际调用。所以,数据都存储在 TiKV 中。另外,TiKV 中的数据都会自动维护多副本(默认为三副本),天然支持高可用和自动故障转移。

    • TiFlash:TiFlash 是一类特殊的存储节点。和普通 TiKV 节点不一样的是,在 TiFlash 内部,数据是以列式的形式进行存储,主要的功能是为分析型的场景加速。

TiDB 数据库的存储

TiDB数据库的存储

  • 键值对 (Key-Value Pair)

    TiKV 的选择是 Key-Value 模型,并且提供有序遍历方法。TiKV 数据存储的两个关键点:

    • 这是一个巨大的 Map(可以类比一下 C++ 的 std::map),也就是存储的是 Key-Value Pairs。

    • 这个 Map 中的 Key-Value pair 按照 Key 的二进制顺序有序,也就是可以 Seek 到某一个 Key 的位置,然后不断地调用 Next 方法以递增的顺序获取比这个 Key 大的 Key-Value。

  • 本地存储(Rocks DB)

    任何持久化的存储引擎,数据终归要保存在磁盘上,TiKV 也不例外。但是 TiKV 没有选择直接向磁盘上写数据,而是把数据保存在 RocksDB 中,具体的数据落地由 RocksDB 负责。这样做的原因是开发一个单机存储引擎工作量很大,特别是要做一个高性能的单机引擎,需要做各种细致的优化,而 RocksDB 是由 Facebook 开源的一个非常优秀的单机 KV 存储引擎,可以满足 TiKV 对单机引擎的各种要求。这里可以简单地认为 RocksDB 是一个单机的持久化 Key-Value Map。

  • Raft 协议

    TiKV 选择了 Raft 算法来保证单机失效的情况下数据不丢失不出错。简单来说,就是把数据复制到多台机器上,这样某一台机器无法提供服务时,其他机器上的副本还能提供服务。这个数据复制方案可靠并且高效,能处理副本失效的情况。

  • Region

    TiKV 选择了按照 Key 划分 Range。某一段连续的 Key 都保存在一个存储节点上。将整个 Key-Value 空间分成很多段,每一段是一系列连续的 Key,称为一个 Region。尽量让每个 Region 中保存的数据不超过一定的大小,目前在 TiKV 中默认是不超过 96MB。每一个 Region 都可以用 [StartKey,EndKey] 这样的左闭右开区间来描述。

  • MVCC

    TiKV实现了多版本并发控制 (MVCC)。

  • 分布式 ACID 事务

    TiKV 的事务采用的是 Google 在 BigTable 中使用的事务模型:Percolator。

搭建测试环境

Kubernetes 集群

本次测试使用三台虚拟机节点部署 Kubernetes 集群,包括 1 个 master 节点和 2 个 worker节点。Kubelete 版本为 1.22.0。

k8s cluster

HwameiStor 本地存储

  1. 在 Kubernetes 集群上部署 HwameiStor 本地存储

    HwameiStor 本地存储

  2. 在两台 worker 节点上分别为 HwameiStor 配置一块 100G 的本地磁盘 sdb

    sdb1

    sdb2

  3. 创建 storagClass

    创建 StorageClass

在 Kubernetes 上部署 TiDB

可以使用 TiDB Operator 在 Kubernetes 上部署 TiDB。TiDB Operator 是 Kubernetes 上的 TiDB 集群自动运维系统,提供包括部署、升级、扩缩容、备份恢复、配置变更的 TiDB 全生命周期管理。借助 TiDB Operator,TiDB 可以无缝运行在公有云或私有部署的 Kubernetes 集群上。

TiDB 与 TiDB Operator 版本的对应关系如下:

TiDB 版本适用的 TiDB Operator 版本
devdev
TiDB >= 5.41.3
5.1 <= TiDB < 5.41.3(推荐),1.2
3.0 <= TiDB < 5.11.3(推荐),1.2,1.1
2.1 <= TiDB < 3.01.0(停止维护)

部署 TiDB Operator

  1. 安装 TiDB CRDs

    kubectl apply -f https://raw.githubusercontent.com/pingcap/tidb-operator/master/manifests/crd.yaml
  2. 安装 TiDB Operator

    helm repo add pingcap https://charts.pingcap.org/ 
    kubectl create namespace tidb-admin
    helm install --namespace tidb-admin tidb-operator pingcap/tidb-operator --version v1.3.2 \
    --set operatorImage=registry.cn-beijing.aliyuncs.com/tidb/tidb-operator:v1.3.2 \
    --set tidbBackupManagerImage=registry.cn-beijing.aliyuncs.com/tidb/tidb-backup-manager:v1.3.2 \
    --set scheduler.kubeSchedulerImageName=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler
  3. 检查 TiDB Operator 组件

    检查 TiDB Operator 组件

部署 TiDB 集群

kubectl create namespace tidb-cluster && \
kubectl -n tidb-cluster apply -f https://raw.githubusercontent.com/pingcap/tidb-operator/master/examples/basic/tidb-cluster.yaml
kubectl -n tidb-cluster apply -f https://raw.githubusercontent.com /pingcap/tidb-operator/master/examples/basic/tidb-monitor.yaml

部署 TiDB 集群

连接 TiDB 集群

yum -y install mysql-client

connecttidb

kubectl port-forward -n tidb-cluster svc/basic-tidb 4000 > pf4000.out & 

连接 TiDB 集群

连接 TiDB 集群

连接 TiDB 集群

检查并验证 TiDB 集群状态

  1. 创建 Hello_world 表

    create table hello_world (id int unsigned not null auto_increment primary key, v varchar(32)); 

    创建 Hello_world 表

  2. 查询 TiDB 版本号

    select tidb_version()\G;

    连接 TiDB 集群

  3. 查询 Tikv 存储状态

    select * from information_schema.tikv_store_status\G;

    查询 Tikv 存储状态

HwameiStor 存储配置

storageClass local-storage-hdd-lvm 分别为 tidb-tikv 及 tidb-pd 创建一个 PVC:

HwameiStor 存储配置

HwameiStor 存储配置

HwameiStor 存储配置

kubectl get po basic-tikv-0 -oyaml

HwameiStor 存储配置

kubectl get po basic-pd-0 -oyaml

HwameiStor 存储配置

测试内容

数据库 SQL 基本能力测试

完成部署数据库集群后,执行了以下基本能力测试,全部通过。

分布式事务

测试目的:支持在多种隔离级别下,实现分布式数据操作的完整性约束即 ACID属性

测试步骤:

  1. 创建测试数据库 CREATE DATABASE testdb

  2. 创建测试用表 CREATE TABLE t_test ( id int AUTO_INCREMENT, name varchar(32), PRIMARY KEY (id) )

  3. 运行测试脚本

测试结果:支持在多种隔离级别下,实现分布式数据操作的完整性约束即 ACID 属性

对象隔离

测试目的:测试不同 schema 实现对象隔离

测试脚本:

create database if not exists testdb;
use testdb
create table if not exists t_test
( id bigint,
name varchar(200),
sale_time datetime default current_timestamp,
constraint pk_t_test primary key (id)
);
insert into t_test(id,name) values (1,'a'),(2,'b'),(3,'c');
create user 'readonly'@'%' identified by "readonly";
grant select on testdb.* to readonly@'%';
select * from testdb.t_test;
update testdb.t_test set name='aaa';
create user 'otheruser'@'%' identified by "otheruser";

测试结果:支持创建不同 schema 实现对象隔离

表操作支持

测试目的:测试是否支持创建、删除和修改表数据、DML、列、分区表

测试步骤:连接数据库后按步骤执行测试脚本

测试脚本:

# 创建和删除表
drop table if exists t_test;
create table if not exists t_test
( id bigint default '0',
name varchar(200) default '' ,
sale_time datetime default current_timestamp,
constraint pk_t_test primary key (id)
);
# 删除和修改
insert into t_test(id,name) values (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
update t_test set name='aaa' where id=1;
update t_test set name='bbb' where id=2;
delete from t_dml where id=5;
# 修改、增加、删除列
alter table t_test modify column name varchar(250);
alter table t_test add column col varchar(255);
insert into t_test(id,name,col) values(10,'test','new_col');
alter table t_test add column colwithdefault varchar(255) default 'aaaa';
insert into t_test(id,name) values(20,'testdefault');
insert into t_test(id,name,colwithdefault ) values(10,'test','non-default ');
alter table t_test drop column colwithdefault;
# 分区表类型(仅摘录部分脚本)
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT NOT NULL,
store_id INT NOT NULL
)

测试结果:支持创建、删除和修改表数据、DML、列、分区表

索引支持

测试目的:验证多种类型的索引(唯一、聚簇、分区、Bidirectional indexes、Expression-based indexes、哈希索引等等)以及索引重建操作。

测试脚本:

alter table t_test add unique index udx_t_test (name);
# 默认就是主键聚簇索引
ADMIN CHECK TABLE t_test;
create index time_idx on t_test(sale_time);
alter table t_test drop index time_idx;
admin show ddl jobs;
admin show ddl job queries 156;
create index time_idx on t_test(sale_time);

测试结果:支持创建、删除、组合、单列、唯一索引

表达式

测试目的:验证分布式数据库的表达式支持 if、casewhen、forloop、whileloop、loop exit when 等语句(上限 5 类)

前提条件:数据库集群已经部署完成。

测试脚本:

SELECT CASE id WHEN 1 THEN 'first' WHEN 2 THEN 'second' ELSE 'OTHERS' END AS id_new  FROM t_test;
SELECT IF(id>2,'int2+','int2-') from t_test;

测试结果:支持 if、case when、for loop、while loop、loop exit when 等语句(上限 5 类)

执行计划解析

测试目的:验证分布式数据库的执行计划解析支持

前提条件:数据库集群已经部署完成。

测试脚本:

explain analyze select * from t_test where id NOT IN (1,2,4);
explain analyze select * from t_test a where EXISTS (select * from t_test b where a.id=b.id and b.id<3);
explain analyze SELECT IF(id>2,'int2+','int2-') from t_test;

测试结果:支持执行计划的解析

执行计划绑定

测试目的:验证分布式数据库的执行计划绑定功能

测试步骤:

  1. 查看 sql 语句的当前执行计划

  2. 使用绑定特性

  3. 查看该 sql 语句绑定后的执行计划

  4. 删除绑定

测试脚本:

explain select * from employees3 a join employees4 b on a.id = b.id where a.lname='Johnson';
explain select /*+ hash_join(a,b) */ * from employees3 a join employees4 b on a.id = b.id where a.lname='Johnson';

测试结果:没有使用 hint 时可能不是 hash_join,使用 hint 后一定是 hash_join。

常用函数

测试目的:验证分布式数据库的标准的数据库函数(支持的函数类型)

测试结果:支持标准的数据库函数

显式/隐式事务

测试目的:验证分布式数据库的事务支持

测试结果:支持显示与隐式事务

字符集

测试目的:验证分布式数据库的数据类型支持

测试结果:目前只支持 UTF-8 mb4 字符集

锁支持

测试目的:验证分布式数据库的锁实现

测试结果:描述了锁的实现方式,R-R/R-W/W-W 情况下阻塞情况,死锁处理方式

隔离级别

测试目的:验证分布式数据库的事务隔离级别

测试结果:支持 si 隔离级别,支持 rc 隔离级别(4.0 GA 版本)

分布式复杂查询

测试目的:验证分布式数据库的分布式复杂查询能力

测试结果:支持跨节点 join 等分布式复杂查询、操作等,支持窗口函数、层次查询

系统安全测试

这部分测试系统安全,完成数据库集群部署后,以下安全测试全部通过。

账号管理与权限测试

测试目的:验证分布式数据库的账号权限管理

测试脚本:

select host,user,authentication_string from mysql.user;
create user tidb IDENTIFIED by 'tidb';
select host,user,authentication_string from mysql.user;
set password for tidb =password('tidbnew');
select host,user,authentication_string,Select_priv from mysql.user;
grant select on *.* to tidb;
flush privileges ;
select host,user,authentication_string,Select_priv from mysql.user;
grant all privileges on *.* to tidb;
flush privileges ;
select * from mysql.user where user='tidb';
revoke select on *.* from tidb;
flush privileges ;
revoke all privileges on *.* from tidb;
flush privileges ;
grant select(id) on test.TEST_HOTSPOT to tidb;
drop user tidb;

测试结果:

  • 支持创建、修改删除账号,并配置和密码,支持安全、审计和数据管理三权分立

  • 根据不同账号,对数库各个级别权限控制包括:实例/库/表/列级别

访问控制

测试目的:验证分布式数据库的权限访问控制,数据库数据通过赋予基本增删改查访问权限控制

测试脚本:

mysql -u root -h 172.17.49.222 -P 4000
drop user tidb;
drop user tidb1;
create user tidb IDENTIFIED by 'tidb';
grant select on tidb.* to tidb;
grant insert on tidb.* to tidb;
grant update on tidb.* to tidb;
grant delete on tidb.* to tidb;
flush privileges;
show grants for tidb;
exit;
mysql -u tidb -h 172.17.49.222 -ptidb -P 4000 -D tidb -e 'select * from aa;'
mysql -u tidb -h 172.17.49.222 -ptidb -P 4000 -D tidb -e 'insert into aa values(2);'
mysql -u tidb -h 172.17.49.222 -ptidb -P 4000 -D tidb -e 'update aa set id=3;'
mysql -u tidb -h 172.17.49.222 -ptidb -P 4000 -D tidb -e 'delete from aa where id=3;'

测试结果:数据库数据通过赋予基本增删改查访问权限控制。

白名单

测试目的:验证分布式数据库的白名单功能

测试脚本:

mysql -u root -h 172.17.49.102 -P 4000
drop user tidb;
create user tidb@'127.0.0.1' IDENTIFIED by 'tidb';
flush privileges;
select * from mysql.user where user='tidb';
mysql -u tidb -h 127.0.0.1 -P 4000 -ptidb
mysql -u tidb -h 172.17.49.102 -P 4000 -ptidb

测试结果:支持 IP 白名单功能,支持 IP 段通配操作

操作日志记录

测试目的:验证分布式数据库的操作监控能力

测试脚本:kubectl -ntidb-cluster logs tidb-test-pd-2 --tail 22

测试结果:记录用户通过运维管理控制台或者 API 执行的关键操作或者错误操作

运维管理测试

这部分测试系统运维,完成数据库集群部署后,以下运维管理测试全部通过。

数据导入导出

测试目的:验证分布式数据库的数据导入导出的工具支持

测试脚本:

select * from sbtest1 into outfile '/sbtest1.csv';
load data local infile '/sbtest1.csv' into table test100;

测试结果:支持按表、schema、database 级别的逻辑导出导入

慢日志查询

测试目的:获取慢查询的 SQL 信息

前提条件:SQL 执行时间需大于配置的慢查询记录阈值,且 SQL 执行完毕

测试步骤:

  1. 调整慢查询阈值到 100ms

  2. 执行 sql

  3. 查看 log/系统表/dashboard 中的慢查询信息

测试脚本:

show variables like 'tidb_slow_log_threshold';
set tidb_slow_log_threshold=100;
select query_time, query from information_schema.slow_query where is_internal = false order by query_time desc limit 3;

测试结果:可以获取慢查询信息

有关测试详情,请查阅 TiDB on hwameiStor 部署及测试记录

· 3 分钟阅读
牛乐川

在 Kubernetes 中,当用户创建一个 PVC,并指定使用 HwameiStor 作为底层存储时,HwameiStor 会创建两类 CR,即本文的主角LocalVolumeLocalVolumeReplica。HwameiStor 为什么为一个 PV 创建这两类资源呢?本文将为您揭开谜团。

LV 副本

LocalVolume

LocalVolume 是 HwameiStor 定义的 CRD,代表 HwameiStor 为用户提供的数据卷。LocalVolume 和 Kubernetes 的 PersistentVolume 是一一对应的,含义也是类似的,均代表一个数据卷。不同之处在于,LocalVolume 记录 HwameiStor 相关的信息,而 PersistentVolume 记录 Kubernetes 平台本身的信息,并关联到 LocalVolume

可以通过以下命令查看系统中 LocalVolume 的详细信息:

#  check status of local volume and volume replica
$ kubectl get lv # or localvolume
NAME POOL KIND REPLICAS CAPACITY ACCESSIBILITY STATE RESOURCE PUBLISHED AGE
pvc-996b05e8-80f2-4240-ace4-5f5f250310e2 LocalStorage_PoolHDD LVM 1 1073741824 k8s-node1 Ready -1 22m

既然 HwameiStor 可以通过 LocalVolume 表示一个数据卷,为什么还需要 LocalVolumeReplica 呢?

LocalVolumeReplica

LocalVolumeReplica 也是 HwameiStor 定义的 CRD。但是与 LocalVolume 不同,LocalVolumeReplica 代表数据卷的副本。

在 HwameiStor 中,LocalVolume 会指定某个属于它的 LocalVolumeReplica 作为当前激活的副本。可以看出LocalVolume 可以拥有多个 LocalVolumeReplica,即一个数据卷可以有多个副本。目前 HwameiStor 会在众多副本中激活其中一个,被应用程序挂载,其他副本作为热备副本。

可以通过以下命令查看系统中 LocalVolumeReplica 的详细信息:

$ kubectl get lvr # or localvolumereplica
NAME KIND CAPACITY NODE STATE SYNCED DEVICE AGE
pvc-996b05e8-80f2-4240-ace4-5f5f250310e2-v5scm9 LVM 1073741824 k8s-node1 Ready true /dev/LocalStorage_PoolHDD/pvc-996b05e8-80f2-4240-ace4-5f5f250310e2 80s

有了卷副本(LocalVolumeReplica)的概念后,HwameiStor 作为一款本地存储系统,具备了一些很有竞争力的特性,例如数据卷的HA,迁移,热备,Kubernetes 应用快速恢复等等。

总结

其实 LocalVolumeLocalVolumeReplica 在很多存储系统中都有引入,是个很通用的概念。只是通过这一概念,实现了各具特色的产品,在解决某个技术难点的时候也可能采取不同的解决方案,因此而适合于不同的生产场景。

随着 HwameiStor 的迭代和演进,我们将会提供更多的能力,从而适配越来越多的使用场景。无论您是用户还是开发者,欢迎您加入 HwameiStor 的大家庭!

· 3 分钟阅读
李洁

今日播报: 独属于系统运维实施人员的自动可靠的云原生本地存储维护系统 — HwameiStor Reliable Helper System 已上线 。

「DaoCloud 道客」正式开源「云原生自动可靠本地存储维护系统HwameiStor Reliable Helper System」。目前尚在 Alpha 阶段。

HwameiStor 将 HDD、SSD 和 NVMe 磁盘形成本地存储资源池进行统一管理,而在磁盘作为上层应用使用的底层数据底座,面临自然和人为损坏等风险,因而磁盘运维维护管理系统Reliable Helper System 诞生。

欢迎广大技术开发者和爱好者前来试用

系统架构

在云原生时代, 应用开发者可以专注于业务逻辑本身,而应用运行时所需的敏捷性、扩展性、可靠性等,则下沉到基础设施软件和运维团队。HwameiStor Reliable Helper System 正是满足云原生时代要求的可靠性运维系统,目前支持一键更换磁盘功能

全面增强运维可靠维护系统

可靠、一键更换、告警提示

  • 可靠数据迁移及数据回填

    可以通过自动识别raid磁盘与否,进行判断是否需要数据迁移和回填,保障数据可靠性。

  • 一键硬盘更换

    通过新旧硬盘唯一uuid来实现一键硬盘更换操作。

  • 直观告警提示

    一键换盘过程中,存在换盘异常信息,进行及时预警。

加入我们

如果说未来是智能互联时代,那么程序员就是通往未来的领路人,开源社区就是程序员们的 “元宇宙”。

目前,「HwameiStor 云原生本地储存系统」已经正式在 Github 开源上线,对它感兴趣的话,就来加入我们吧,一起开垦这块属于程序员的 “元宇宙” 新土地,成为未来行道者。

· 4 分钟阅读
要海峰

HwameiStor

今日播报: 独属于程序员们的、自由演化的 “元宇宙” 新土地 — HwameiStor 云原生本地存储系统,等您来开垦。

「DaoCloud 道客」正式开源「云原生本地储存系统HwameiStor」。HwameiStor 将 HDD、SSD 和 NVMe 磁盘形成本地存储资源池进行统一管理,使用 CSI 架构提供分布式的本地数据卷服务,为有状态的云原生应用或组件提供数据持久化能力,欢迎广大技术开发者和爱好者前去试用

系统架构

在云原生时代, 应用开发者可以专注于业务逻辑本身,而应用运行时所需的敏捷性、扩展性、可靠性等,则下沉到基础设施软件和运维团队。HwameiStor 正是满足云原生时代要求的储存系统。 它具有高可用、自动化、低成本、快速部署、高性能等优点,可以替代昂贵的传统 SAN 存储

智、稳、敏 全面增强本地存储

  • 自动化运维管理

    可以自动发现、识别、管理、分配磁盘。 根据亲和性,智能调度应用和数据。自动监测磁盘状态,并及时预警。

  • 高可用的数据

    使用跨节点副本同步数据, 实现高可用。发生问题时,会自动将应用调度到高可用数据节点上,保证应用的连续性。

  • 丰富的数据卷类型

    聚合 HDD、SSD、NVMe 类型的磁盘,提供非低延时,高吞吐的数据服务。

  • 灵活动态的线性扩展

    可以根据集群规模大小进行动态的扩容,灵活满足应用的数据持久化需求。

丰富应用场景 广泛适配企业需求

  • 适配高可用架构中间件

    Kafka、ElasticSearch、Redis等,这类中间件应用自身具备高可用架构,同时对数据的 IO 访问有很高要求。HwameiStor 提供的基于 LVM 的单副本本地数据卷,可以很好地满足它们的要求。

  • 为应用提供高可用数据卷

    MySQL 等 OLTP 数据库,要求底层存储提供高可用的数据存储,当发生问题时可快速恢复数据,同时,也要求保证高性能的数据访问。HwameiStor 提供的双副本的高可用数据卷,可以很好地满足此类需求。

  • 自动化运维传统存储软件

    MinIO、Ceph 等存储软件,需要使用 Kubernetes 节点上的磁盘,可以采用 PVC/PV 的方式,通过 CSI 驱动自动化地使用 HwameiStor 的单副本本地卷,快速响应业务系统提出的部署、扩容、迁移等需求,实现基于 Kubernetes 的自动化运维。

加入我们

如果说未来是智能互联时代,那么程序员就是通往未来的领路人,开源社区就是程序员们的 “元宇宙”。

目前,「HwameiStor 云原生本地储存系统」已经正式在 Github 开源上线,对它感兴趣的话,就来加入我们吧,一起开垦这块属于程序员的 “元宇宙” 新土地,成为未来行道者。

· 一分钟阅读
要海峰

Welcome to the Hwameistor blog space.

Here you can keep up with the progress of the Hwameistor open source project and recent hot topics.

We also plan to include release notes for major releases, guidance articles, community-related events, and possibly some development tips, and interesting topics within the team.

If you are interested in contributing to this open source project and would like to join the discussion or make some guest blog posts, please contact us.

GitHub address is: https://github.com/hwameistor