当前位置: 首页 > 编程日记 > 正文

第17章 使用iSCSI服务部署网络存储

章节概述:

本章节将分析SCSI与iSCSI技术结构的不同,了解iSCSI技术的优势、SAN存储网络技术结构以及iSCSI HBA卡的作用。
完整演示部署iSCSI target服务程序的方法流程:创建RAID阵列(5)后使用targetcli命令发布到iSCSI存储目录并创建ACL列表。
配置使用iSCSI initiator服务程序发现、连接并使用iSCSI存储设备,最后编辑fstab文件将存储设备设置为开机启动。

本章目录结构

  • 17.1 网络存储技术
  • 17.2 部署iSCSI存储
    • 17.2.1 配置iSCSI服务端
    • 17.2.2 配置iSCSI客户端
17.1 网络存储技术

传统的SCSI小型计算机系统接口(Small Computer System Interface)技术是存储设备最基本的标准协议,但通常需要设备互相靠近并用SCSI总线链接,因此受到了物理环境的限制。

iSCSI小型计算机系统接口(即Internet Small Computer System Interface)则是由IBM公司研究开发用于实现在IP网络上运行SCSI协议的新存储技术,即能够让SCSI接口与以太网技术相结合,使用iSCSI协议基于以太网传送SCSI命令与数据,克服了SCSI需要直接连接存储设备的局限性,使得我们可以跨越不同的服务器共享存储设备,并可以做到不停机状态下扩展存储容量。

SAN存储区域网络技术(Storage Area Network)便是基于iSCSI存储协议,采用高速光钎通道传输存储数据的服务程序。
iSCSI结构拓扑

本图为SAN结构拓扑

服务器会基于iSCSI协议将SCSI设备、命令与数据打包成标准的TCP/IP包然后通过IP网络传输到目标存储设备,而远端存储设备接收到数据包后需要基于iSCSI协议将TCP/IP包解包成SCSI设备、命令与数据,这个过程无疑会消耗系统CPU资源,因此我们可以将SCSI协议的封装动作交由独立的iSCSI HBA硬件卡来处理,减少了对服务器性能的影响。
ISCSI HBA卡

本图中设备为iSCSI HBA卡

但坦白来讲iSCSI技术还是存在诸多问题的,如距离与带宽之间的矛盾关系,虽然iSCSI满足了数据长距离传输的需求,但现在广域网的带宽还是不够理想,IP网络的速率和延迟都是iSCSI传输数据的巨大障碍。

17.2 部署iSCSI存储

iSCSI的工作方式分为服务端(target)与客户端(initiator):

服务端:即存放硬盘或RAID设备的存储端,目的是为客户端提供可用的存储。
客户端:使用服务端的服务器主机。

本实验需要两台虚拟主机来完成,分别是:

编辑
主机名称操作系统IP地址
iscsi服务端红帽RHEL7操作系统192.168.10.10
iscsi客户端红帽RHEL7操作系统192.168.10.20

逻辑单元LUN(即Logical Unit Number)是使用iSCSI协议中的重要概念,因为当客户机想要使用服务端存储设备时都必需输入对应的名称(Target ID),而一个服务端可能会同时提供多个可用的存储设备,于是便用LUN来详细的描述设备或对象,同时每个LUN Device可能代表一个硬盘或RAID设备,LUN的名称由用户指定。

17.2.1 配置iSCSI服务端

第1步:准备作为LUN发布的存储设备。

在前面的存储结构章节中学习了使用mdadm工具创建RAID磁盘冗余阵列的方法,忘记就翻回去看下吧~

在虚拟机中再添加4块硬盘:

虚拟机添加硬盘

创建RAID5并设置1块备份故障盘:

[root@linuxprobe ~]# mdadm -Cv /dev/md0 -n 3 -l 5 -x 1 /dev/sdb /dev/sdc /dev/sdd /dev/sde
mdadm: layout defaults to left-symmetric
mdadm: layout defaults to left-symmetric
mdadm: chunk size defaults to 512K
mdadm: size set to 20954624K
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.

查看RAID阵列的详细信息,记录下UUID的值:

[root@linuxprobe ~]# mdadm -D /dev/md0
/dev/md0:Version : 1.2Creation Time : Thu Sep 24 21:59:57 2015Raid Level : raid5Array Size : 41909248 (39.97 GiB 42.92 GB)Used Dev Size : 20954624 (19.98 GiB 21.46 GB)Raid Devices : 3Total Devices : 4Persistence : Superblock is persistentUpdate Time : Thu Sep 24 22:02:23 2015State : clean Active Devices : 3
Working Devices : 4Failed Devices : 0Spare Devices : 1Layout : left-symmetricChunk Size : 512KName : linuxprobe.com:0  (local to host linuxprobe.com)          UUID : 3370f643:c10efd6a:44e91f2a:20c71f3eEvents : 26Number   Major   Minor   RaidDevice State0       8       16        0      active sync   /dev/sdb1       8       32        1      active sync   /dev/sdc4       8       48        2      active sync   /dev/sdd3       8       64        -      spare   /dev/sde

创建RAID阵列配置文件:

[root@linuxprobe ~]# vim /etc/mdadm.conf
DEVICE /dev/sdb /dev/sdc /dev/sdd /dev/sde
ARRAY /dev/md0 UUID=3370f643:c10efd6a:44e91f2a:20c71f3e

第2步:安装iSCSI target服务程序:

[root@linuxprobe ~]# yum -y install targetd targetcli
Loaded plugins: langpacks, product-id, subscription-manager
………………省略部分安装信息………………
Dependencies Resolved
================================================================================Package                  Arch        Version                  Repository  Size
================================================================================
Installing:targetcli                noarch      2.1.fb34-1.el7           rhel7       55 ktargetd                  noarch      0.7.1-1.el7              rhel7       48 k
Installing for dependencies:PyYAML                   x86_64      3.10-11.el7              rhel7      153 klibyaml                  x86_64      0.1.4-10.el7             rhel7       55 klvm2-python-libs         x86_64      7:2.02.105-14.el7        rhel7      153 kpyparsing                noarch      1.5.6-9.el7              rhel7       94 kpython-configshell       noarch      1:1.1.fb11-3.el7         rhel7       64 kpython-kmod              x86_64      0.9-4.el7                rhel7       57 kpython-rtslib            noarch      2.1.fb46-1.el7           rhel7       75 kpython-setproctitle      x86_64      1.1.6-5.el7              rhel7       15 kpython-urwid             x86_64      1.1.1-3.el7              rhel7      654 k
Transaction Summary
================================================================================
Install  2 Packages (+9 Dependent packages)
………………省略部分安装信息………………
Complete!

启动iSCSI target服务程序:

[root@linuxprobe ~]# systemctl start targetd

将iSCSI target服务程序添加到开机启动项:

[root@linuxprobe ~]# systemctl enable targetd
ln -s '/usr/lib/systemd/system/targetd.service' '/etc/systemd/system/multi-user.target.wants/targetd.service'

第3步:创建存储对象。
targetcli命令用于管理iSCSI target存储设备,格式为:“targetcli”

[root@linuxprobe ~]# targetcli
Warning: Could not load preferences file /root/.targetcli/prefs.bin.
targetcli shell version 2.1.fb34
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

查看当前的存储目录树:

/> ls
o- / ..................................................................... [...]
o- backstores .......................................................... [...]
| o- block .............................................. [Storage Objects: 0]
| o- fileio ............................................. [Storage Objects: 0]
| o- pscsi .............................................. [Storage Objects: 0]
| o- ramdisk ............................................ [Storage Objects: 0]
o- iscsi ........................................................ [Targets: 0]
o- loopback ..................................................... [Targets: 0]

进入/backstores/block目录中:

/> cd /backstores/block
/backstores/block>

使用/dev/md0创建设备disk0:

/backstores/block> create disk0 /dev/md0
Created block storage object disk0 using /dev/md0.

返回到根目录中:

/backstores/block> cd ..
/backstores> cd ..
/> 

查看创建后的设备:

/> ls
o- / ..................................................................... [...]o- backstores .......................................................... [...]| o- block .............................................. [Storage Objects: 1]| | o- disk0 ..................... [/dev/md0 (40.0GiB) write-thru deactivated]| o- fileio ............................................. [Storage Objects: 0]| o- pscsi .............................................. [Storage Objects: 0]| o- ramdisk ............................................ [Storage Objects: 0]o- iscsi ........................................................ [Targets: 0]o- loopback ..................................................... [Targets: 0]

第4步:配置iSCSI target目标。
进入到iscsi目录中:

/> cd iscsi
/iscsi> 

创建iSCSI target目标:

/iscsi> create
Created target iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80.
Created TPG 1.

依次进入到target的luns目录中:

/iscsi> cd iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80/
/iscsi/iqn.20....d497c356ad80> ls
o- iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80 ...... [TPGs: 1]o- tpg1 ............................................... [no-gen-acls, no-auth]o- acls .......................................................... [ACLs: 0]o- luns .......................................................... [LUNs: 0]o- portals .................................................... [Portals: 0]
/iscsi/iqn.20....d497c356ad80> cd tpg1/
/iscsi/iqn.20...c356ad80/tpg1> cd luns
/iscsi/iqn.20...d80/tpg1/luns> 

创建LUN设备:

/iscsi/iqn.20...d80/tpg1/luns> create /backstores/block/disk0 
Created LUN 0.

第5步:设置访问控制列表。
切换到acls目录中:

/iscsi/iqn.20...d80/tpg1/luns> cd ..
/iscsi/iqn.20...c356ad80/tpg1> cd acls 

创建访问控制列表:

/iscsi/iqn.20...d80/tpg1/acls> create iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80:client
Created Node ACL for iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80:client
Created mapped LUN 0.

切换到portals目录中:

/iscsi/iqn.20...d80/tpg1/acls> cd ..
/iscsi/iqn.20...c356ad80/tpg1> cd portals 

添加允许监听的IP地址:

/iscsi/iqn.20.../tpg1/portals> create 192.168.10.10
Using default IP port 3260
Created network portal 192.168.10.10:3260.

查看配置概述后退出工具:

/iscsi/iqn.20.../tpg1/portals> ls /
o- / ........................... [...]o- backstores................. [...]| o- block ................... [Storage Objects: 1]| | o- disk0 ................. [/dev/md0 (40.0GiB) write-thru activated]| o- fileio .................. [Storage Objects: 0]| o- pscsi ................... [Storage Objects: 0]| o- ramdisk ................. [Storage Objects: 0]o- iscsi ..................... [Targets: 1]| o- iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80 .... [TPGs: 1]|   o- tpg1 .................. [no-gen-acls, no-auth]|     o- acls ........................................................ [ACLs: 1]|     | o- iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80:client [Mapped LUNs: 1]|     |   o- mapped_lun0 ............................................. [lun0 block/disk0 (rw)]  o- luns .................... [LUNs: 1]|     | o- lun0 .............. [block/disk0 (/dev/md0)]|     o- portals ............. [Portals: 1]|       o- 192.168.10.10:3260  [OK]o- loopback .................. [Targets: 0]
/> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/target/backup.
Configuration saved to /etc/target/saveconfig.json

第4步:创建防火墙允许规则:

[root@linuxprobe ~]# firewall-cmd --permanent  --add-port=3260/tcp
success
[root@linuxprobe ~]# firewall-cmd --reload
success
17.2.2 配置iSCSI客户端

首先检查能够与iscsi服务端通信:

[root@linuxprobe ~]# ping -c 4 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.959 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.469 ms
64 bytes from 192.168.10.10: icmp_seq=3 ttl=64 time=0.465 ms
64 bytes from 192.168.10.10: icmp_seq=4 ttl=64 time=0.277 ms--- 192.168.10.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.277/0.542/0.959/0.253 ms

红帽RHEL7系统已经默认安装了iscsi客户端服务程序:

[root@linuxprobe ~]# yum install iscsi-initiator-utils
Loaded plugins: langpacks, product-id, subscription-manager
Package iscsi-initiator-utils-6.2.0.873-21.el7.x86_64 already installed and latest version
Nothing to do

编辑的iscsi客户端名称文件:
该名称是initiator客户端的唯一标识,读者可以按照我的方法修改,也可以用iscsi-iname命令随机生成~都可以的。

[root@linuxprobe ~]# vim /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80:client

重启iscsi客户端服务程序:

[root@linuxprobe ~]# systemctl restart iscsid

将iscsi客户端服务程序添加到开机启动项中:

[root@linuxprobe ~]# systemctl enable iscsid
ln -s '/usr/lib/systemd/system/iscsid.service' '/etc/systemd/system/multi-user.target.wants/iscsid.service'

发现iscsi服务端的可用存储设备:
iscsiadm命令用于管理(插入、查询、更新或删除)iSCSI数据库配置文件的命令行工具,格式见下面演示。

[root@linuxprobe ~]# iscsiadm -m discovery -t st -p 192.168.10.10
192.168.10.10:3260,1 iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80

连接iscsi服务端的可用存储设备:

[root@linuxprobe ~]# iscsiadm -m node -T iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80 -p 192.168.10.10 --login
Logging in to [iface: default, target: iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80, portal: 192.168.10.10,3260] (multiple)
Login to [iface: default, target: iqn.2003-01.org.linux-iscsi.linuxprobe.x8664:sn.d497c356ad80, portal: 192.168.10.10,3260] successful.

此时便多了一块硬盘设备:

[root@linuxprobe ~]# file /dev/sdb 
/dev/sdb: block special

格式化、挂载后查看容量信息:

[root@linuxprobe ~]# mkfs.xfs /dev/sdb
log stripe unit (524288 bytes) is too large (maximum is 256KiB)
log stripe unit adjusted to 32KiB
meta-data=/dev/sdb               isize=256    agcount=16, agsize=654720 blks=                       sectsz=512   attr=2, projid32bit=1=                       crc=0
data     =                       bsize=4096   blocks=10475520, imaxpct=25=                       sunit=128    swidth=256 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=5120, version=2=                       sectsz=512   sunit=8 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@linuxprobe ~]# mkdir /iscsi
[root@linuxprobe ~]# mount /dev/sdb /iscsi
[root@linuxprobe ~]# df -h
Filesystem             Size  Used Avail Use% Mounted on
/dev/mapper/rhel-root   18G  3.4G   15G  20% /
devtmpfs               734M     0  734M   0% /dev
tmpfs                  742M  176K  742M   1% /dev/shm
tmpfs                  742M  8.8M  734M   2% /run
tmpfs                  742M     0  742M   0% /sys/fs/cgroup
/dev/sr0               3.5G  3.5G     0 100% /media/cdrom
/dev/sda1              497M  119M  379M  24% /boot
/dev/sdb                40G   33M   40G   1% /iscsi

查看设备的UUID值:

[root@linuxprobe ~]# blkid | grep /dev/sdb
/dev/sdb: UUID="eb9cbf2f-fce8-413a-b770-8b0f243e8ad6" TYPE="xfs" 

设置为开机后自动挂载时因为iSCSI服务程序基于IP网络传输数据,所以我们必需在fstab文件中添加参数_netdev,代表网络联通后再挂载:

[root@linuxprobe ~]# vim /etc/fstab
UUID=eb9cbf2f-fce8-413a-b770-8b0f243e8ad6 /iscsi xfs defaults,_netdev 0 0

转载于:https://www.cnblogs.com/linux130/p/5778881.html

相关文章:

【仿去哪儿】骆驼动画加载

简单的实现正在加载的动画,比较粗糙,没有实现后面的旋转地球。图一为去哪儿的截图,图二为本文实现的效果 图1 图2 一、新建LoadView继承自UIView,声明几个方法,这样在项目需要用到时,直接调用就行&#xff…

来自极客标签10款最新设计素材-系列十六

本周我们推荐来自极客标签社区带来的10款免费设计素材,大家可以在这里免费下载你需要的内容。如果你也有更好的作品,欢迎分享到社区中来,在得到帮助的同时,也能与更多人分享来自你的作品。 免费图标:扁平风格的图标集…

python简介、安装及基本设置

python简介 1、Python的定义: Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色…

MVC会员注册

自从写了《数据库数据加密与解密》http://www.cnblogs.com/insus/p/3434735.html。其中也有提及Insus.NET将要在MVC应用程序中实现会员注册的功能。一段时间来,工作繁忙,这个星六还要值班。现在算是忙里偷闲,继续写MVC的程序。本次要实现会员…

继承,基类,派生类

在 C中,继承机制通过类的派生实现,被继承的类称为基类或父类;在继承类的基础上创建的新类称为派生类或子类。派生类的定义格式为:class 派生类名:继承方式基类名 1,继承方式基类名 2,…,继承方式基类名 n{派生类增加的成员声明;};…

【仿去哪儿】滑动隐藏导航栏

仿照去哪儿,隐藏导航栏(其实是设置为透明背景):向下滑动到时,当顶部图片看不见时,显示导航栏,源代码下载,效果如下: 主要思想:就是监听UITableView的滑动事件…

Python基本知识以及if语句

注释 什么时候需要注释? 对于复杂的操作,应该在操作开始前写若干行注释,目的是增加可读性,注释应该和代码至少离开两个空格 单行注释(两种方式) 多行注释(一种方式) ####if语句&…

通过pip安装模块

环境:ubuntu,python2/3 命令: pip3 install ipy  # 通过pip3给python3.x安装ipypip3 install --upgrade pip  # 升级pippip install ipy  # 通过pip给python2.x安装ipy 如果显示程序“pip/pip3”尚未安装 sudo apt-get install python3…

按照文字内容动态设置TableViewCell的高度

最近再做个项目需要使用UITableView来显示评论列表,但是有的评论字数特别多,固定的Cell高度显示不完,只能动态地根据字数来设置Cell的高度了 只要实现UITableViewDelegate的 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIn…

分享十款免费数据恢复软件

绝大多数的数据恢复软件都可以帮助你恢复被删除的文件。免费数据恢复软件可帮助你“取消删除”或者恢复电脑中的文件。那些你已经删除而且最近从回收站清空的文件仍然存在硬盘上(或介质卡或USB驱动器等),也可以通过这些免费数据恢复软件轻松地…

Python 字符串及基本语句

#####1、break break: 某一条件满足的时候&#xff0c;退出循环&#xff0c;不再执行后续重复的代码 在循环体内部&#xff0c;我们可以增加额外的条件&#xff0c;在需要的时候&#xff0c;跳出整个循环 i 0 while i <10: if i 3: break print i i 1 print ‘over’ #…

javascript 方法实例

输出对象的属性名称与值 &#xff1a; boj(o){for(var p in o){console.log(p ":" o[p] "\n"); } } 构造函数&#xff1a; var o new Object(); 构造函数通过不使用return关键字&#xff0c;它通过初始化新对象 if(a)else{b} //如果不是a就返…

ISAPI在IIS7上的配置

主要介绍ISAPI的作用、ISAPI在IIS7上的配置、开发ISAPI的基本内容及使用VS 2008配置ISAPI DLL开发项目。 一、ISAPI介绍 缩写词Internet Server Application Programming Interface为Microsoft所提的Internet server的API 。 ISAPI分为两种&#xff1a;ISAPI extension &#x…

iOS自定义转场动画

图1是最近闲着做的一个项目&#xff1a;午睡闹钟&#xff08;欢迎到AppStore下载&#xff0c;截稿时最新版还在审核&#xff09;的截图&#xff0c;把其中的转场动画效果简单封装了一下写了个demo&#xff08;图2&#xff09;&#xff0c;demo的备注写的比较清楚&#xff0c;de…

Python中if语句练习题

####1、#####if-else语句 #elif和else都必须和if联合使用&#xff0c;不能单独使用 holidy_name 中秋节 if holidy_name 情人节: print 买玫瑰 print 看电影 elif holidy_name 圣诞节: print 吃大餐 elif holidy_name 生日: print 吃蛋糕 print 买礼…

开源:ASP.NET MVC+EF6+Bootstrap开发框架

前言 我在博客园潜水两三年了&#xff0c;在这里看过很多大神的文章&#xff0c;也学到了很多东西。可以说我是汲取着博客园的营养成长的。 想当年&#xff0c;我也是拿10个G的精神粮食从一个博客园大神那里换来一套开发框架&#xff0c;正式走上开发之路&#xff0c;到后来成为…

【iOS官方文档翻译】iOS的蓝牙连接、数据接收及发送

说明&#xff1a;苹果官方开发文档中涉及一些名词&#xff1a;Central&#xff08;中心设备&#xff09;、Peripheral&#xff08;外围设备&#xff09;、advertising&#xff08;广告&#xff09;、Services&#xff08;服务&#xff09;、Characteristic&#xff08;特征&…

checkbox全选与反选

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>全选与反选</title><meta http-equiv"Content-Type" content"text/html;…

元组、列表及其特性

1、 #元组&#xff1a;带了紧箍咒的列表&#xff0c;不可直接修改元组内容 #元组本身不可变数据类型&#xff0c;没有增删改差 #元组内可以存储任意数据类型 t(1,2,3,4.2,star) print t,type(t) #元组内包含可变数组类型&#xff0c;可以间接修改元组内容 t1([1,2,3.3],4,5)…

JZOJ #4722 跳楼机 (最短路模型的完美转化)

题目描述&#xff1a; 给出$h,x,y,z$&#xff0c;求在$h$以内&#xff0c;$x,y,z$可以凑出多少个不同的数。$(1\leq{h}\leq{10^{18}},1\leq{x,y,z}\leq{10^5})$ 解题思路&#xff1a; 直接做显然不好做。我们考虑取$n$个$y$和$m$个$z$&#xff0c;然后再加上$x,2*x,3*x\cdots$&…

【C++】STL队列和栈的使用

C的STL标准模板库提供了队列和栈的基本操作。下面通过两个demo分别介绍STL队列和STL栈的使用。 Demo1&#xff1a;STL队列 【题目】卡片游戏&#xff08;题目来自刘汝佳《算法竞赛入门》&#xff09; 桌上又一叠牌&#xff0c;从第一张牌&#xff08;即位于顶面的牌&#xf…

mongodb的shell命令

MongoDB常用命令&#xff1a; 超级用户相关&#xff1a; use admin #增加或修改用户密码 db.addUser(ixigua,pwd) #查看用户列表 db.system.users.find() #用户认证 db.auth(ixigua,pwd) #删除用户 db.removeUser(mongodb) #查看所有用户 show users #查看所有数据库 show dbs …

字典、集合及其特性

1、 字典的定义 """ 字典是一个无序的数据集合&#xff0c;使用print输出字典的时候 通常输出的顺序和定义的顺序是不一致的 """ message { name:tom, age:18, height:1.80, weight:75.5 } print message s {} prin…

[HDOJ2819]Swap(二分图最大匹配, 匈牙利算法)

题目链接&#xff1a;http://acm.split.hdu.edu.cn/showproblem.php?pid2819 题意&#xff1a;给一张n*n的01矩阵&#xff0c;可以任意交换其中的行或者列&#xff0c;问是否可以交换出来一个对角线上都是1的矩阵。 按行列号建图&#xff0c;如果(i,j)为1的话&#xff0c;则i和…

脚本路径问题_dirname

pwd可获取命令当前的路径 可是若我们想在脚本中获取脚本所在文件夹的路径&#xff0c;这种方法是不够用的。 例如&#xff0c;我们的脚本放在/home/user/script/下&#xff0c;名字叫做getpath.sh getpath.sh有一行脚本是了local_path$(pwd) 现在我们在/home/user/下&#xff0…

【iOS官方文档翻译】iOS蓝牙的基本概念

之前写了【iOS官方文档翻译】iOS的蓝牙连接、数据接收及发送一文&#xff0c;介绍了怎样进行蓝牙通讯&#xff0c;但是很多基本概念没有进行解释&#xff0c;看起来可能有点吃力&#xff0c;所以现在再翻译一篇苹果对官方蓝牙4.0一些基本概念介绍的文章。 1.中心设备和外围设备…

元组、列表、字典及集合练习

列表练习题&#xff1a; #假定有下面这样的列表: #names [lily, denny, jenny, apple] #输出结果为:I have lily,denny, jenny and apple. names [lily, denny, jenny, apple] print I have ,.join(names[:-1]) and names[-1] 2、后台管理前台会员信息 要求&#…

【iOS】sqlite3的使用(増删改查)

目录&#xff1a; 一、sqlite3常用函数 二、将sqlite3集成到项目&#xff0c;实现増删改查 三、封装DBManager 四、Demo 一、sqlite3常用函数及解释 &#xff08;1&#xff09;sqlite3_open: 用来创建和打开数据库文件&#xff0c;接收两个参数&#xff0c;第一个是数据库…

网上搜集了点资料,学web的人互相分享共同进步吧(php编码的好习惯必须养成)...

网上搜集了点资料&#xff0c;学web的人互相分享共同进步吧 一、优秀的代码应该是什么样的&#xff1f; 优秀的PHP代码应该是结构化的。大段的代码应该被分割整理成一个个函数或方法&#xff0c;而那些不起眼的小段代码则应该加上注释&#xff0c;以便日后清楚它们的用途。而且…

div模拟textarea文本域轻松实现高度自适应——张鑫旭

by zhangxinxu from http://www.zhangxinxu.com本文地址&#xff1a; http://www.zhangxinxu.com/wordpress/?p1362 一、关于textarea文本域以及高度自适应 textarea标签为表单元素&#xff0c;一般用在多行文字的输入。在web应用上常见的是评论输入框&#xff0c;微博信息输入…