文章目录
Multipath
多路径是解决什么问题的?
下文主要参考:
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/dm_multipath/index
主机-硬盘多对一访问
- 一对一访问:普通主机都是一个硬盘挂接到一个总线上,即主机和硬盘一对一访问。
- 多对一访问:在由光纤组成的SAN环境,或者由iSCSI组成的IP-SAN环境,由于主机和硬盘通过了光纤交换机或者多块网卡及IP来连接,就构成了主机和硬盘多对一的关系。也就是说,主机到硬盘可以有多条路径可以选择。主机到硬盘之间的IO由多条路径可以选择。
主机-硬盘多对一访问带来的问题
- 负载均衡:每个主机到硬盘是有多条路径,如果同时使用这些路径,I/O流量如何分配?
- 故障处理:其中有路径HBA卡、交换机、端口等故障了,如何处理?
- 设备识别:在操作系统的角度来看,每条路径,操作系统会认为是一个实际存在的物理盘,但实际上只是通向同一个物理盘的不同路径而已,用户如何规划使用这些设备?
解决多对一访问带来的问题(多路径)
多路径就是用来解决上述问题的,其原理就是基于每个物理设备的wwid(全球唯一id),方法如下:
- 多路径软件通过wwid将访问某一个设备的多个子路径合并成为一个虚拟路径,解决上面说的问题(3)设备识别。
- 通过AA、ALUA、AP等多路径技术实现虚拟路径中多个子路径的访问控制和流量控制,解决上面的问题(1)负载均衡。
- 通过故障时识别网络状态,实现虚拟路径中子访问路径的切换,解决上面的问题(2)故障处理。
多路径技术
路径状态
访问端口组有如下状态,在相应访问状态下,阵列控制器只能回应相应的命令标准(命令标准由ISO/IEC SPC-3制定),这就决定了在某一时刻是否可以通过某个目标端口访问逻辑单元。
- active/optimal(ao):工作控制器所在端口组状态
- active/non-optimal(ano):只能回应相应的命令标准,可以过渡到ao
- unablialable:不相应读写命令时的端口组状态
- standby:只能回应相应的命令标准,可以过渡到ao
- offline:离线状态
- transition:临时状态,表示端口组状态正在切换
多路径模式
不同的多路径模式就是根据上面不同的路径状态组合而成。下文主要参考如下文章并总结:
https://www.360blogs.top/alua/
https://blog.csdn.net/Pipcie/article/details/105038262
https://blog.51cto.com/u_15127636/2770220
A/A-S(Active/Acivie-Symmetric)
- 路径状态:目标端口均处于主动/优化(active/optimized)状态。
- IO处理:多个控制器之间通过PCIe或Infiniband等实现高速互联的通讯,从主机侧发送一个IO到控制器端后,多个控制器可同时参与IO处理。
- 负载均衡:存储系统会自动负载均衡,当一个控制器繁忙或业务压力较大时,存储系统不需要主机端多路径负载均衡软件参与就可以自动实现负载均衡。
A/A-A(Active/Active-Asymmetric,ALUA)
- 路径状态:只有一个控制器的目标端口组处于主动/优化(Active/Optimized)状态,其他控制器的目标端口组处于主动/非优化(Active/Unoptimized)状态。
- IO处理:某个时刻一个特定LUN只属于某一个优选控制器,在多路径的配合下,IO从优选控制的IO组(Active/Optimized)下发IO,多路径不会发送该LUN的IO到其他控制器。
- 隐式ALUA:支持查询LUN的端口组不对称访问状态;正常情况下,主机查询LUN的端口组信息,识别控制器的优先级,从优先级最高(Active/Optimized)的控制器下发业务,当Active/Optimized链路故障后,主机选择其他的链路下(Active/Unoptimized)发业务。
- 显式ALUA:支持查询和设置LUN的端口组不对称访问状态,当Active/Optimized链路断开后,主机设置其他控制器的优先级为最优;主机从新的最优的控制器下发业务(通过LUN TresPass实现优选控制器切换)。
- 负载均衡:一般通过将LUN A归属控制器A,将LUNB归属给控制器B实现两边的负载均衡,归属操作可以手动或自动完成。
A/P(Active/Passive)
- 路径状态:只有一个控制器的目标端口处于主动/优化(Active/Optimized)状态,其他控制器的目标端口处于备用或平时不工作状态。
- IO处理:由于多路径和存储互不相识(多路径不知道那些路径是优选路径),IO很难选到合适的路径,IO的下发可以说这完全取决于上层多路径的心情,解决方案是提供自研多路径来配合阵列选路,通过私有协议实现IO到优选路径的匹配。
- 负载均衡:同A/A-A。一般通过将LUN A归属控制器A,将LUNB归属给控制器B实现两边的负载均衡,归属操作可以手动或自动完成。
Ceph-iSCSI如何支持多路径
下文参考代码:
https://github.com/ceph/ceph-iscsi
https://github.com/open-iscsi/rtslib-fb
状态路径
参考下面代码可知,每个添加到target中的lun有一个owner portal,此portal的路径状态为active/optimal,其他路径在implicit模式时为active/non-optimal,在explicit模式时为active/standby。
def alua_format_group_name(tpg, failover_type, is_owner):
if is_owner:
return "ao"
if failover_type == "explicit":
return "standby{}".format(tpg.tag)
else:
return "ano{}".format(tpg.tag)
def alua_create_ao_group(so, tpg, group_name):
alua_tpg = ALUATargetPortGroup(so, group_name, tpg.tag)
alua_tpg.alua_support_active_optimized = 1
alua_tpg.alua_access_state = 0 # 设置active/optimal
return alua_tpg
def alua_create_implicit_group(tpg, so, group_name, is_owner):
if is_owner:
alua_tpg = alua_create_ao_group(so, tpg, group_name)
else:
alua_tpg = ALUATargetPortGroup(so, group_name, tpg.tag)
alua_tpg.alua_access_state = 1 # 设置active/non-optimal
alua_tpg.alua_support_active_nonoptimized = 1
alua_tpg.alua_access_type = 1
# Just make sure we get to at least attempt one op for the failover
# process.
alua_tpg.implicit_trans_secs = settings.config.osd_op_timeout + 15
return alua_tpg
def alua_create_explicit_group(tpg, so, group_name, is_owner):
if is_owner:
alua_tpg = alua_create_ao_group(so, tpg, group_name)
alua_tpg.preferred = 1
else:
alua_tpg = ALUATargetPortGroup(so, group_name, tpg.tag)
alua_tpg.alua_support_standby = 1
# Use Explicit but also set the Implicit bit so we can
# update the kernel from configfs.
alua_tpg.alua_access_type = 3
# start ports in Standby, and let the initiator drive the initial
# transition to AO.
alua_tpg.alua_access_state = 2 # 设置active/standby
return alua_tpg
def alua_create_group(failover_type, tpg, so, is_owner):
group_name = alua_format_group_name(tpg, failover_type, is_owner)
if failover_type == "explicit":
alua_tpg = alua_create_explicit_group(tpg, so, group_name, is_owner)
elif failover_type == "implicit":
# tmp drop down to implicit. Next patch will check for "implicit"
# and add error handling up the stack if the failover_type is invalid.
alua_tpg = alua_create_implicit_group(tpg, so, group_name, is_owner)
else:
raise CephiSCSIInval("Invalid failover type {}".format(failover_type))
alua_tpg.alua_support_active_optimized = 1
alua_tpg.alua_support_offline = 0
alua_tpg.alua_support_unavailable = 0
alua_tpg.alua_support_transitioning = 1
alua_tpg.nonop_delay_msecs = 0
return alua_tpg
上文alua_access_state状态参考如下rtslib代码:
alua_access_state = property(_get_alua_access_state, _set_alua_access_state,
doc="Get or set ALUA state. "
"0 = Active/optimized, "
"1 = Active/non-optimized, "
"2 = Standby, "
"3 = Unavailable, "
"4 = LBA Dependent, "
"14 = Offline, "
"15 = Transitioning")
支持ALUA模式
根据上面的路径状态可知,ceph-iscsi只能支持ALUA模式。
参考文献
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/dm_multipath/index
https://www.360blogs.top/alua/
https://blog.csdn.net/Pipcie/article/details/105038262
https://blog.51cto.com/u_15127636/2770220