多路径(multi-path)介绍及使用 (hp刀片机适用)

普通的电脑主机都是一个硬盘挂接到一个总线上,这里是一对一的关系。而到了有光纤组成的SAN环境,由于主机和存储通过了光纤交换机连接,这样的话,就构成了多对多的关系。也就是说,主机到存储可以有多条路径可以选择。主机到存储之间的IO由多条路径可以选择,如下图:

根据上图所示,每个主机到所对应的存储可以经过几条不同的路径,如果是同时使用的话,I/O流量如何分配?其中一条路径坏掉了,如何处理?还有在操作系统的角度来看,每条路径,操作系统会认为是一个实际存在的物理盘,但实际上只是通向同一个物理盘的不同路径而已,这样是在使用的时候,就给用户带来了困惑。多路径软件就是为了解决上面的问题应运而生的。多路径的主要功能就是和存储设备一起配合实现如下功能:

1.故障的切换和恢复
2.IO流量的负载均衡
3.磁盘的虚拟化

由于多路径软件是需要和存储在一起配合使用的,不同的厂商基于不同的操作系统,都提供了不同的版本。并且有的厂商,软件和硬件也不是一起卖的,如果要使用多路径软件的话,可能还需要向厂商购买license才行。比如EMC公司基于linux下的多路径软件,就需要单独的购买license。好在, RedHat和Suse的2.6的内核中都自带了免费的多路径软件包,并且可以免费使用,同时也是一个比较通用的包,可以支持大多数存储厂商的设备,即使是一些不是出名的厂商,通过对配置文件进行稍作修改,也是可以支持并运行的很好的。

---Linux 内置 HBA 驱动程序和内置多路径计划(HP) 

 从 Red Hat RHEL 5.2 和 Novell SLES 10 SP2 开始的惠普支持的客户选项 

 选项一: 惠普提供的 Emulex HBA 驱动程序和 Multipulse 故障转移,或者惠普提供的 Emulex HBA 驱动程序和内置 Device Mapper Multipathing 
 选项二: 惠普提供的 QLogic HBA 驱动程序和 QLogic 故障转移,或者惠普提供的单一路径模式 QLogic HBA 驱动程序和内置 Device Mapper Multipathing 
 选项三: 内置 HBA 驱动程序和内置 Device Mapper Multipathing。 该选项仅用于非生产环境 


---Linux的multipath需要以下工具包:
1. multipath-tools 应该也就是rpm包device-mapper-multipath。主要提供multipathd和multipath等工具和 multipath.conf等配置文件。这些工具通过device mapper的ioctr的接口创建和配置multipath设备(调用device-mapper的用户空间库。创建的多路径设备会在/dev /mapper中)。

2. device-mapper.linux device mapper主要包括两大部分:内核部分和用户部分。内核部分主要由device mapper核心(dm.ko)和一些target driver(md-multipath.ko)。核心完成设备的映射,而target根据映射关系和自身特点具体处理从mappered device 下来的i/o。同时,在核心部分,提供了一个接口,用户通过ioctr可和内核部分通信,以指导内核驱动的行为,比如如何创建mappered device,这些divece的属性等。linux device mapper的用户空间部分主要包括device-mapper这个包。其中包括dmsetup工具和一些帮助创建和配置mappered device的库。这些库主要抽象,封装了与ioctr通信的接口,以便方便创建和配置mappered device。multipath-tool的程序中就需要调用这些库。

3. dm-multipath.ko和dm.ko。dm.ko是device mapper驱动。它是实现multipath的基础。dm-multipath其实是dm的一个target驱动。

4. scsi_id 包含在udev程序包中,可以在multipath.conf中配置该程序来获取scsi设备的序号。通过序号,便可以判断多个路径对应了同一设备。这个是多路径实现的关键。scsi_id是通过sg驱动,向设备发送EVPD page80或page83 的inquery命令来查询scsi设备的标识。但一些设备并不支持EVPD 的inquery命令,所以他们无法被用来生成multipath设备。但可以改写scsi_id,为不能提供scsi设备标识的设备虚拟一个标识符,并输出到标准输出。multipath程序在创建multipath设备时,会调用scsi_id,从其标准输出中获得该设备的scsi id。在改写时,需要修改scsi_id程序的返回值为0。因为在multipath程序中,会检查该直来确定scsi id是否已经成功得到。



---具体安装过程描述如下:
RHEL4U7 & 光纤网卡等驱动已经安装完成后。

1. 多路径软件包的构成 (都在光盘目录内)

device-mapper-1.02.13xxx.rpm,该软件运行在底层,主要进行设备虚拟化和映射(系统已经自动安装)。
device-mapper-multipath-0.4.7xxx.rpm( Debian等版本Linux内的软件包命名为:multipath-tools-xxx) ,这个软件包可以在多路径的管理和监控工具,主要进行路径状态的检测,管理工作.安装完成后,使用命令modprobe dm_multipath来加载相应的模块,可以使用lsmod |grep dm_multipath来检查安装是否正常。

    ---It is recommended that DM be integrated into the boot sequence using the following commands:
    # chkconfig --add multipathd
    # chkconfig multipathd on

    ---Use the following commands to initialize and start DM for the first time:
    # modprobe dm-multipath
    # modprobe dm-round-robin
    # service multipathd start
    # multipath –v2


2. 下载并安装HPDM Multipath Enablement Kit for HP StorageWorks Disk Arrays v4.2.0 available at http://www.hp.com/go/devicemapper.

3、修改配置文件/etc/multipath.conf , 主要是针对multipaths 字段,定义各wwid别名(文章后部有详细说明);其他字段使用默认设定即可,当然也可按照硬件设备自定义。

4、mulitipath服务
# /etc/init.d/multipathd start

5、使用  multipath -F 删除现有路径

6、multipath -v2 格式化路径
---Run command /sbin/multipath –v2. This will invoke multipathd daemon to re-read the multipath.conf file and generate the /dev/mapper/<WWN> (/dev/mapper/alias) and /dev/dm-x device nodes.

7、使用 multipath -ll 查看多路径
# multipath -ll
ocs1 (3600508b40006ea6e0001a000002a0000) dm-2 HP,HSV210
[size=500G][features=1 queue_if_no_path][hwhandler=0]
\_ round-robin 0 [prio=100][active]
\_ 0:0:2:1 sdc 8:32  [active][ready]
\_ 0:0:3:1 sdd 8:48  [active][ready]
\_ round-robin 0 [prio=20][enabled]
\_ 0:0:0:1 sda 8:0   [active][ready]
\_ 0:0:1:1 sdb 8:16  [active][ready]

7、使用fdisk -l 查看多路径的情况
# fdisk -l

Disk /dev/cciss/c0d0: 146.7 GB, 146778685440 bytes
255 heads, 63 sectors/track, 17844 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

           Device Boot      Start         End      Blocks   Id  System
/dev/cciss/c0d0p1   *           1          13      104391   83  Linux
/dev/cciss/c0d0p2              14       17844   143227507+  8e  Linux LVM

Disk /dev/sda: 536.8 GB, 536870912000 bytes
255 heads, 63 sectors/track, 65270 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/sda doesn't contain a valid partition table

Disk /dev/sdb: 536.8 GB, 536870912000 bytes
255 heads, 63 sectors/track, 65270 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/sdb doesn't contain a valid partition table

8. 对于Oracle安装中的Storage使用,如OCR & VOTE、ASM等应用,建议都使用独立LUN, 这样在LUN的权限分配等方面更灵活。

9. 后续Oracle等应用安装,参考Oracle或第三方说明文件
----------------------------------
http://bbs.chinaunix.net/archiver/?tid-1301434.html
http://blog.chinaunix.net/u/15278/showart_1777934.html
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c00710472/c00710472.pdf?jumpid=reg_R1002_USEN
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c01388403/c01388403.pdf?jumpid=reg_R1002_USEN

http://www.oracle.com/global/de/community/dbadmin/tipps/multipath_udev/index.html
http://www.oracle.com/technology/tech/linux/validated-configurations/html/vc_dell2970-oel4-rhel4-md3000_1.html?rssid=valconfig

http://www.redhat.com/docs/manuals/csgfs/pdf/DM_Multipath-4_6.pdf
http://www.oracle.com/technology/products/database/asm/pdf/device-mapper-udev-crs-asm%20rh4.pdf
http://www.oracle.com/global/ch-de/events/information_experience/downloads/21_ORACLE_RAC_with_ASM_on_Linux%20.pdf
http://tonykorn97.itpub.net/get/6414/Device%20Mapper%20Multipath%20Configuration%20Guide%20for%20HP%20StorageWorks%20Arrays.pdf
http://www-03.ibm.com/support/techdocs/atsmastr.nsf/5cb5ed706d254a8186256c71006d2e0a/a96abd4202a6d5918625735d0058fee0/$FILE/10GRAC_SLES10_R4.pdf

-----------------------


---在/etc/multipath.conf 中定义各LUN别名的方式:

1. 在系统中,执行fdisk -l 可以看到

Disk /dev/sda: 145.9 GB, 145999527936 bytes
255 heads, 63 sectors/track, 17750 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          25      200781   83  Linux
/dev/sda2              26        3849    30716280   83  Linux
/dev/sda3            3850        4893     8385930   82  Linux swap / Solaris
/dev/sda4            4894       17750   103273852+   5  Extended
/dev/sda5            4894       17750   103273821   83  Linux

Disk /dev/sdb: 1395.8 GB, 1395864371200 bytes
255 heads, 63 sectors/track, 169704 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/sdb doesn't contain a valid partition table

Disk /dev/sdc: 1395.8 GB, 1395864371200 bytes
255 heads, 63 sectors/track, 169704 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/sdc doesn't contain a valid partition table

Disk /dev/sdd: 1395.8 GB, 1395864371200 bytes
255 heads, 63 sectors/track, 169704 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/sdd doesn't contain a valid partition table

Disk /dev/sde: 1395.8 GB, 1395864371200 bytes
255 heads, 63 sectors/track, 169704 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/sde doesn't contain a valid partition table

其中,sdb,sdc,sdd,sde为通过多路径看到的两块磁盘,此处显示为4块。

输入multipath -v3可以看到

[root@mailMx1 etc]# multipath -v3
dm-0: blacklisted
.
.
sdb: path checker = hp_sw (controller setting)
sdb: getprio = /sbin/mpath_prio_alua /dev/%n (controller setting)
sdb: getuid = /sbin/scsi_id -g -u -s /block/%n (controller setting)
sdb: uid = 3600508b4001013f70001900004230000 (callout)
.
sdc: vendor = COMPAQ
sdc: product = HSV111 (C)COMPAQ
sdc: rev = 4100
.
.
.
maildata2: set ACT_NOTHING (map unchanged)

根据以上信息,就可以直接编辑配置文件,位于/etc/multipath.conf ,主要修改以下部分

将本机硬盘从多路径中去掉,
blacklist {
        devnode "^sda"
}

添加多路径映射设备,其中别名alias可以自己起。
multipaths {
        multipath {
                wwid                    3600508b4001013f70001900004230000
                alias                   maildata1
                path_grouping_policy    multibus
                path_checker            tur
                path_selector           "round-robin 0"
        }
        multipath {
                wwid                    3600508b4001013f70001900004320000
                alias                   maildata2
                path_grouping_policy    multibus
                path_checker            tur
                path_selector           "round-robin 0"
        }
}

添加多路径设备,注意要用到前面收集的信息,特别是path_checker要和前面一致

devices {
       device {
    vendor                 "COMPAQ|HP"                 //厂商名称
    product             "HSV111 \(C\)COMPAQ"            //产品型号
    path_grouping_policy         group_by_prio                 //默认的路径组策略
    getuid_callout             "/sbin/scsi_id -p 0x80 -g -u -s /block/%n" //获得唯一设备号使用的默认程序
    path_checker             hp_sw                     //决定路径状态的方法
    path_selector             "round-robin 0"             //选择那条路径进行下一个IO操作的方法
    prio_callout             "/sbin/mpath_prio_alua /dev/%n"        //获取有限级数值使用的默认程序
    failback             immediate                 //故障恢复的模式
    hardware_handler         "0"                     //确认用来在路径切换和IO错误时,执行特定的操作的模块。
    no_path_retry             queue                     //在disable queue之前系统尝试使用失效路径的次数的数值
    rr_min_io             100                     //在当前的用户组中,在切换到另外一条路径之前的IO请求的数目
       }
}

这样,使用multipath -ll就可以看到

[root@mailMx1 etc]#  multipath -ll
maildata2 (3600508b4001013f70001900004320000) dm-1 COMPAQ,HSV111 (C)COMPAQ
[size=1.3T][features=1 queue_if_no_path][hwhandler=0]
\_ round-robin 0 [prio=60][active]
 \_ 3:0:0:2 sdc 8:32  [active][ready]
 \_ 3:0:1:2 sde 8:64  [active][ready]
maildata1 (3600508b4001013f70001900004230000) dm-0 COMPAQ,HSV111 (C)COMPAQ
[size=1.3T][features=1 queue_if_no_path][hwhandler=0]
\_ round-robin 0 [prio=60][active]
 \_ 3:0:0:1 sdb 8:16  [active][ready]
 \_ 3:0:1:1 sdd 8:48  [active][ready]

说明设备已经配置完毕,可以看到,我们将4个设备聚合成了两个设备,分别是maildata1和maildata2。这两个设备的位置在/dev/mapper下。 

2. 默认情况下,将使用 /var/lib/multipath/bindings 内的配置设定具体每个多路径设备名,如果在/etc/multipath.conf中有设定各wwid 别名,别名会覆盖此设定。



----负载均衡测试
使用dd命令来对设备进行写操作,并同时通过iostat来查看I/0状态,命令及输出如下:

#dd if=/dev/zero of=/dev/vgtest/lvtest1
avg-cpu: %user %nice %sys %iowait %idle
0.50 0.00 3.47 48.51 47.52

Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 0.00 0.00 0.00 0 0
sdf 756.57 6044.44 0.00 5984 0
sdh 0.00 0.00 0.00 0 0
sdj 0.00 0.00 0.00 0 0
sdl 334.34 2682.83 0.00 2656 0

通过上述输出,我们看到,在对/dev/vgtest/lvtest1读写时,实际上是通过对/dev/md-0包含的当前active的所有设备,即/dev/sdf,/dev/sdl这2条路径来完成对实际的LUN的写过程。

---路径切换测试
首先,我们拔掉服务器上A口的光纤线,经过不到10秒,我们看到:MPIO成功地从上述“失败”的路径/dev/sdl切换到了另外一条路径/dev/sdf上。其输出样本如下:

#iostat 1
avg-cpu: %user %nice %sys %iowait %idle
0.50 0.00 6.47 46.77 46.27

Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 0.98 0.00 7.84 0 8
sdf 1709.80 13678.43 0.00 13952 0
sdh 0.00 0.00 0.00 0 0
sdj 0.00 0.00 0.00 0 0
sdl 0.00 0.00 0.00 0 0


When devices are brought under the control of device-mapper-multipath the new multipathed devices can be seen in three different places under the /dev directory: /dev/dm-N, /dev/mapper/mpathN and /dev/mpath/mpathN.

   --- The /dev/dm-N  devices are internal to device mapper and should never be used. These devices are not persistent. Starting with Red Hat Enterprise Linux 5, these devices are no longer created by udev.
   --- The /dev/mpath/mpathN  devices are provided so that all the multipathed devices can be seen in one place. However, these device nodes may not be created on boot before the system needs to access them. Therefore they should not be used for creating logical volumes or filesystems.
   --- The /dev/mapper/mpathN  devices are persistent and they are created early in the boot process. Therefore these are the device names that should be used to access the multipathed devices.


--------------------------------更新: 2011/11/01---------------------------------------------
多路径,理论上看起来复杂,但是具体到应用/设定,很简单:

1. 安装多路径软件包;
device-mapper-1.02.13xxx.rpm,该软件运行在底层,主要进行设备虚拟化和映射(系统已经自动安装)。
device-mapper-multipath-0.4.7xxx.rpm ,此软件包RHEL5默认已经安装;

2. 安装FC HBA 驱动; 当前的新版Linux已经自带多数FC HBA驱动;
    此时如果需要安装官方驱动,比如安装HP提供的 HP 81E HBA驱动,需要注意其说明内指定的支持OS版本范围;虽然RHEL5.7已经发布,但是HP的驱动仅仅支持到RHEL5.6 , 强行安装的话,只会导致报错甚至系统崩溃;

3. 更新/etc/multipath.conf 设定文件, 可参考后续第六步;

4. 设定multipathd 服务自动启动并初始化;
    chkconfig multipathd on
    multipath -F
    multipath -v2

5. mulitpath -ll ,  看到下列类似输入,表示已经成功!
mpath0 (36001438005dee7fd0000500000a00000) dm-2 HP,HSV400
[size=500G][features=1 queue_if_no_path][hwhandler=0][rw]
\_ round-robin 0 [prio=200][active]
 \_ 2:0:3:1 sdb 8:16  [active][ready]
 \_ 2:0:6:1 sdc 8:32  [active][ready]
 \_ 3:0:3:1 sdf 8:80  [active][ready]
 \_ 3:0:7:1 sdh 8:112 [active][ready]
\_ round-robin 0 [prio=40][enabled]
 \_ 2:0:2:1 sda 8:0   [active][ready]
 \_ 2:0:7:1 sdd 8:48  [active][ready]
 \_ 3:0:1:1 sde 8:64  [active][ready]
 \_ 3:0:5:1 sdg 8:96  [active][ready]


6. 以下为HP提供的 HPDMmultipath-4.4.1.tar.gz 所提供的 multipath.conf 文件,供参考; 该软件包貌似可以不需要安装:

### Donot edit the first two lines of this file or remove this file
### HP Device Mapper Multipath Enablement Kit v4.4.1

### The Device Mapper Multipath Template configuration file for RHEL5U4
### or later releases to be used with HP Storageworks Arrays.

### Use this configuration file as your /etc/multipath.conf file.
### If you already have a valid working configuration file, refer here 
### for the recommended configuration for HP arrays.

### For a list of configuration options with descriptions, please refer 
### to /usr/share/doc/<multipath-tools-version>/multipath.conf.annotated 

# The defaults section 
defaults {
    udev_dir        /dev
    polling_interval    10
    selector        "round-robin 0"
    path_grouping_policy    failover
    getuid_callout        "/sbin/scsi_id -g -u -s /block/%n"
    prio_callout        "/bin/true"
    path_checker        tur
    rr_min_io        100
    rr_weight           uniform
    failback        immediate
    no_path_retry        12
    user_friendly_names    yes
}

# The blacklist section - use this to blacklist a multipath device based on 
# it's wwid ( using wwid ) or device names ( using devnode ) or
# vendor and product id ( using device block).

blacklist {
#    wwid        26353900f02796769
    devnode        "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
    devnode     "^hd[a-z][[0-9]*]"
#    devnode        "^cciss!c[0-9]d[0-9]*"
#    device {
#        vendor "HP"
#        product    "OPEN-*"
#    }
}

# The blacklist_exceptions section - to list device names to be treated 
# as multipath candidates even if they are on the blacklist.

# Note: blacklist exceptions are only valid in the same class.
#       It is not possible to blacklist devices using the devnode keyword
#       and to exclude some devices of them using the wwid keyword.

#blacklist_exceptions {
#    wwid        2345234245647657
#    devnode        "sda"
#    device {
#        vendor    "HP"
#        product    "OPEN-*"
#    }
#}

# The multipaths section - uncomment this section to define a per multipath
# device settings.
#multipaths {
# uncomment the multipath block to modify the settings of a multipath device
# based on its wwid

#multipath {
#    wwid            2039485769900000000
#    alias            red
#    path_grouping_policy    group_by_prio
#    path_selector        "round-robin 0"
#    failback        immediate
#    rr_weight        uniform    
#    no_path_retry        10
#    rr_min_io        100
#}

#}

# The devices section - used to define per storage array model settings
devices {

# If you are already using a valid configuration file and do not have a 
# device subsection for HP arrays, please add the appropriate device subsection 
# for the respective arrays from the entries below.
# If you already have a device subsection for HP arrays which has different 
# parameters from the entries below, modify it appropriately.

# For EVA A/A arrays

device {
    vendor            "HP|COMPAQ"
    product         "HSV1[01]1 \(C\)COMPAQ|HSV2[01]0|HSV300|HSV4[05]0"
    path_grouping_policy    group_by_prio
        getuid_callout        "/sbin/scsi_id -g -u -s /block/%n"
        path_checker        tur
        path_selector        "round-robin 0"
        prio_callout        "/sbin/mpath_prio_alua /dev/%n"
        rr_weight        uniform
        failback        immediate
    hardware_handler    "0"
        no_path_retry        18
    rr_min_io        100
}

# For HP P2000 family 
device {
        vendor                  "HP"
        product                 "P2000 G3 FC|P2000G3 FC/iSCSI"
        path_grouping_policy    group_by_prio
        getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
        path_checker            tur
        path_selector           "round-robin 0"
        prio_callout            "/sbin/mpath_prio_alua /dev/%n"
        rr_weight               uniform
        failback                immediate
        hardware_handler        "0"
        no_path_retry           18
        rr_min_io               100
}

# For XP arrays
device {
        vendor            "HP"
        product            "OPEN-.*"
        path_grouping_policy    multibus
        getuid_callout        "/sbin/scsi_id -g -u -s /block/%n"
    path_selector        "round-robin 0"
        rr_weight        uniform
        path_checker        tur
    hardware_handler    "0"
        failback        immediate
        no_path_retry        18
    rr_min_io        1000
}

# For MSA A/A arrays
device {
        vendor                  "HP"
        product                 "MSA VOLUME*"
        path_grouping_policy    group_by_prio
        getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
        path_checker            tur
        path_selector           "round-robin 0"
        prio_callout            "/sbin/mpath_prio_alua /dev/%n"
        rr_weight               uniform
        failback                immediate
        hardware_handler        "0"
        no_path_retry           18
        rr_min_io               100
}

# For MSA2xxxsa arrays
device {
        vendor                  "HP"
        product                 "MSA2012sa|MSA2312sa|MSA2324sa"
        path_grouping_policy    group_by_prio
        getuid_callout          "/sbin/scsi_id -g -u -n -s /block/%n"
        path_checker            tur
        path_selector           "round-robin 0"
        prio_callout            "/sbin/mpath_prio_alua %d"
        rr_weight               uniform
        failback                immediate
        hardware_handler        "0"
        no_path_retry           18
        rr_min_io               100
}

# For MSA23xxfc and MSA23xxi arrays
device {
        vendor                  "HP"
        product                 "MSA2312fc|MSA2324fc|MSA2312i|MSA2324i"
        path_grouping_policy    group_by_prio
        getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
        path_checker            tur
        path_selector           "round-robin 0"
        prio_callout            "/sbin/mpath_prio_alua /dev/%n"
        rr_weight               uniform
        failback                immediate
        hardware_handler        "0"
        no_path_retry           18
        rr_min_io               100
}

# For MSA20xxfc, MSA22xxfc and MSA20xxi arrays
device {
        vendor            "HP"
        product            "MSA2[02]12fc|MSA2012i"
        path_grouping_policy    multibus
        getuid_callout        "/sbin/scsi_id -g -u -s /block/%n"
    path_selector        "round-robin 0"
        rr_weight        uniform
        path_checker        tur
    hardware_handler    "0"
        failback        immediate
        no_path_retry        18
    rr_min_io        100
}
# To blacklist a device by vendor and product say, to blacklist a XP device 
# uncomment the below block

#device {
#    vendor            "HP"
#    product_blacklist    "OPEN-.*"
#}

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值