Curve 是云原生计算基金会 (CNCF) Sandbox 项目,是网易数帆发起开源的高性能、易运维、云原生的分布式存储系统。

为了让大家更容易使用以及了解 Curve,我们期望接下来通过系列应用实践文章,以专题的形式向大家展示 Curve。

本篇文章是Curve块存储应用实践的第一篇,该系列文章包括:

  • Curve块存储应用实践一部曲之iSCSI
  • Curve块存储应用实践二部曲之nbd
  • Curve块存储应用实践三部曲之云主机
  • Curve块存储应用实践四部曲之云原生数据库
  • Curve块存储应用实践五部曲之性能调优

iSCSI 及 tgt 简介

tgt 是一个开源 iSCSI 服务器,详情请见 tgt githu[1]。我们在开发 Curve 块设备服务器时,想让更多的系统能够使用 Curve 块设备,而不仅仅是 Linux 系统,iSCSI 协议是一个广泛使用的块设备协议,我们想修改 tgt 以便让 Curve 提供 iSCSI 服务。

Curve 块存储

为tgt提供了访问 Curve 的驱动,详见部署网络高性能版本tgt[2] , 文档里有操作步骤,这样用户就可以在任何支持 iSCSI 的操作系统上使用 Curve 块设备存储,例如Windows。

Curve 在初步使用 tgt 时也遇到一些问题:

我们观察到原版 tgt 使用单一主线程 epoll 来处理 iSCSI 命令,还包括管理平面的 unix domian socket 也在这个主线程里。

在10 Gbit/s 网络上甚至更快的网络上,单线程(也即单cpu)处理 iSCSI 命令的速度已经跟不上需求了,一个线程对付多个target的情况下,多个iSCSI Initiator的请求速度稍微高一点,这个单线程的cpu使用率就100%忙碌。

所以本文的重点就是介绍tgt的性能优化。同时社区用户使用过程中还遇到了nebd服务的单点和性能问题,社区用户对此也进行了优化,详情可参考创云融达基于 Curve 的智慧税务场景实践。

Curve 对 tgt 的性能优化实践

1. 使用多个线程做 epoll

实现多个event loop线程,每个线程负责一定数量的socket connection上的iSCSI命令处理。这样就能发挥多cpu的处理能力。

2. 为每个 target 创建一个 epoll 线程

为了避免多个target共享一个epoll时依然可能出现超过单个cpu处理能力的问题,我们为每一个 target设置了一个epoll线程。target epoll的cpu使用由OS负责调度,这样在各target上可以 实现公平的cpu使用。当然如果网络速度再快,依然会出现单个epoll线程处理不过来一个iSCSI target上的请求,但是目前这个方案依然是我们能做的最好方案。

3. 管理平面

管理平面保持了与原始tgt的兼容性。从命令行使用方面来说,没有任何区别,没有任何修改。管理平面在程序的主线程上提供服务,主线程也是一个epoll loop线程,这与原始的tgt没有区别,它负责target,lun,login/logout,discover,session, connection等的管理。当Intiator连接到iSCSI 服务器时,总是先被管理平面线程所服务,如果该connection最后需要创建session去访问某个target,那么该connection会被迁移到对应的target的epoll线程上去。

4. 数据结构的锁

为每一个target提供一个mutex,当target epoll线程在运行时,这把锁是被该线程锁住的,这样该线程可以任意结束一个sesssion或connection,当线程进入epoll_wait时,这把锁是释放了的,epoll_wait返回时又会锁住这把锁。我们修改了相关代码,让这个epoll线程不用遍历target list,只存取它服务的target相关结构,这样我们不需要target列表锁。管理面也会增加、删除一个session或者connection时,也需要锁住这把target锁。所以管理面和target epoll线程使用这个mutex来互斥,这样就可以安全地访问对应target上的session和connection了。

5. connection 建立 session

当login_finish成功时,login_finish有时候会创建session(如果没有session存在)。login_finish在connection结构的字段migrate_to里设置目标iSCSItarget。

6. 什么时候做 connection 迁移

当调用返回到iscsi_tcp_event_handler时,因为login_finish设置了migrate_to目标target,iscsi_tcp_event_handler就锁住目标iscsi target结构,并把该connection的fd插入到目标target的evloop 里面,完成迁移。

7. 设置 pthread name

设置各target event loop的线程在top中的名为tgt/n, n为target id,这样容易用top之类的工具观察哪一个target占用的cpu高。

8. 举个例子

假如MGMT要删除一个target,下面的代码说明了流程:

/* called by mgmt */
tgtadm_err tgt_target_destroy(int lld_no, int tid, int force)
{
struct target *target;
struct acl_entry *acl, *tmp;
struct iqn_acl_entry *iqn_acl, *tmp1;
struct scsi_lu *lu;
tgtadm_err adm_err; eprintf("target destroy\n"); /*
* 这里因为控制面是单线程的,而且SCSI IO线程不会删除target,
* 所以我们找target的时候并不需要锁
*/ target = target_lookup(tid);
if (!target)
return TGTADM_NO_TARGET; /*
* 这里要锁住target,因为我们要删除数据结构,所以不能和iscsi io
* 线程一起共享,必须在scsi 线程释放了锁时进行
*/ target_lock(target);
if (!force && !list_empty(&target->it_nexus_list)) {
eprintf("target %d still has it nexus\n", tid);
target_unlock(target);
return TGTADM_TARGET_ACTIVE;
}

/* 以上步骤删除了所有资源 ,可以释放锁了 */
target_unlock(target);
if (target->evloop != main_evloop) {
/* 通知target上的evloop停止,并等待evloop 线程退出 */
tgt_event_stop(target->evloop);
if (target->ev_td != 0)
pthread_join(target->ev_td, NULL);
/* 下面把evloop的资源删除干净 */
work_timer_stop(target->evloop);
lld_fini_evloop(target->evloop);
tgt_destroy_evloop(target->evloop);
}

性能优化结果

我们为tgt配置了3块盘,一块 Curve 块存储卷,两块本地盘

 <target iqn.2019-04.com.example:curve.img01>
backing-store cbd:pool//iscsi_test_
bs-type curve
</target> <target iqn.2019-04.com.example:local.img01>
backing-store /dev/sde
</target><target iqn.2019-04.com.example:local.img02>
backing-store /dev/sdc
</target>

使用本机登录iscsi iscsiadm --mode node --portal 127.0.0.1:3260 --login

为fio设置存取这些 iSCSI 的块设备,使用:

[global]
rw=randread
direct=1
iodepth=128
ioengine=aio
bsrange=16k-16k
runtime=60
group_reporting [disk01]
filename=/dev/sdx [disk02]
filename=/dev/sdy
size=10G [disk03]
filename=/dev/sdz
size=10G

测试结果如下:

下面是未经优化的fio成绩,IOPS 38.8K

下面是经过多线程优化的fio成绩,IOPS 60.9K

<原创作者:徐逸锋,Curve PMC>

参考[1]:https://github.com/fujita/tgt

参考[2]:https://github.com/opencurve/...

【点击了解更多网易技术】

Curve 块存储应用实践 -- iSCSI的更多相关文章

  1. 远程块存储iSCSI

    /* Border styles */ #table-2 thead, #table-2 tr { border-top-width: 1px; border-top-style: solid; bo ...

  2. 探索 OpenStack 之(9):深入块存储服务Cinder (功能篇)

    继研究了Neutron之后,继续Nova的外围研究之旅.本站是研究块存储服务Cinder. 0.验证环境 环境包括: 1.一个controller节点,运行nova-api, nova-schedul ...

  3. 【恒天云技术分享系列10】OpenStack块存储技术

    原文:http://www.hengtianyun.com/download-show-id-101.html 块存储,简单来说就是提供了块设备存储的接口.用户需要把块存储卷附加到虚拟机(或者裸机)上 ...

  4. 【openstack N版】——块存储服务cinder

    一.块存储服务介绍 1.1块存储服务通常包含以下组件 cinder-api: 接受API请求,并将其路由到"cinder-volume"执行. cinder-volume: 与块存 ...

  5. cinder块存储 后端采用lvm、nfs安装配置

    #cinder块存储 后端采用lvm.nfs安装配置 openstack pike 安装 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html #cinder ...

  6. 存储那些事儿(三):OpenStack的块存储Cinder与商业存储的融合

    OpenStack是一个美国国家航空航天局和Rackspace合作研发的云端运算‎软件,以Apache许可证授权,并且是一个自由软件和开放源代码项目.OpenStack是IaaS(基础设施即服务)‎软 ...

  7. OpenStack-Ocata版+CentOS7.6 云平台环境搭建 —9.块存储服务(cinder)部署配置

    块存储服务部署相关块存储服务(cinder)为实例提供块存储.存储的分配和消耗是由块存储驱动器,或者多后端配置的驱动器决定的.还有很多驱动程序可用:NAS/SAN,NFS,ISCSI,Ceph等.典型 ...

  8. Openstack块存储cinder安装配置

    openstack service create --name cinderv2 \ --description "OpenStack Block Storage" volumev ...

  9. 025-Cinder服务-->安装并配置一个本地存储节点(ISCSI)

    一:Cinder提供块级别的存储服务,块存储提供一个基础设施为了管理卷,以及和OpenStack计算服务交互,为实例提供卷.此服务也会激活管理卷的快照和卷类型的功能,块存储服务通常包含下列组件:cin ...

  10. 云计算管理平台之OpenStack块存储服务cinder

    一.cinder简介 cinder是openstack环境中的块存储服务,主要为运行在openstack之上的虚拟机提供块存储服务的:所谓块存储就是我们经常用的硬盘呀,U盘啊,SD卡等等这些块设备的, ...

随机推荐

  1. tomcat的catalina.out日志按自定义时间格式进行分割

    默认情况下,tomcat的catalina.out日志文件是没有像其它日志一样,按日期进行分割,而是全部输出全部写入到一个catalina.out,这样日积月累就会造成.out日志越来越大,给管理造成 ...

  2. frps服务端与nginx可共用443端口

    转载自: https://www.ioiox.com/archives/78.html frps服务器上的nginx frps.ini配置 由于nginx占用80/443端口,frps.ini中的 v ...

  3. 配置logstash消费kafka多个topic,分别生成索引

    filebeat配置多个topic #filebeat.prospectors: filebeat.inputs: - input_type: log encoding: GB2312 # field ...

  4. 关闭You have new mail in /var/spool/mail/root提醒

    echo "unset MAILCHECK">> /etc/profile #以root权限执行 或者用sudo source /etc/profile cat /de ...

  5. Linux+Proton without Steam玩火影忍者究极风暴4指南

    首先你需要Proton7.0 without Steam,使用说明和下载链接看这里https://www.cnblogs.com/tubentubentu/p/16716612.html 启动游戏的命 ...

  6. POJ3417 Network暗的连锁 (树上差分)

    树上的边差分,x++,y++,lca(x,y)-=2. m条边可以看做将树上的一部分边覆盖,就用差分,x=1,表示x与fa(x)之间的边被覆盖一次,m次处理后跑一遍dfs统计子树和,每个节点子树和va ...

  7. .NET 6 跨服务器联表查询

    一.大家是否有这个需求 1.跨品种查询 :比如 MYSQL和一个SQLSERVER进行联表查询 ,或者SQLITE和MYSQL进行联表查询 2.跨服务器查询 : A服务器和B服务器查询 如果想同时支持 ...

  8. 华为云ubunbu部署.NetCore3.1项目(DDD商城)

    提前项目打包发布,文件传输工具Filezilla,注意是选择sftp协议,将publish文件传到/home文件夹下 第一步  .NetCoreSDK安装 微软官方的文档https://docs.mi ...

  9. 自己动手写ls命令——Java版

    自己动手写ls命令--Java版 介绍 在前面的文章Linux命令系列之ls--原来最简单的ls这么复杂当中,我们仔细的介绍了关于ls命令的使用和输出结果,在本篇文章当中我们用Java代码自己实现ls ...

  10. sql面试50题------(11-20)

    文章目录 11.查询至少有一门课与学号为'01'的学生所学课程相同的学生的学号和姓名 12.查询和'01'号同学所学课程完全相同的其他同学的学号 13.查询两门及其以上不及格课程的同学的学号,姓名及其 ...