Интерфейс подключения сервера fc lc. Протокол Fibre Channel. Гарантированный порядок доставки

  • Tutorial

В Perl заложено огромное количество возможностей, которые, на первый взгляд, выглядят лишними, а в неопытных руках могут вообще приводить к появлению багов. Доходит до того, что многие программисты, регулярно пишущие на Perl, даже не подозревают о полном функционале этого языка! Причина этого, как нам кажется, заключается в низком качестве и сомнительном содержании литературы для быстрого старта в области программирования на Perl. Это не касается только книг с Ламой, Альпакой и Верблюдом («Learning Perl », «Intermediate Perl » и «Programming Perl ») - мы настоятельно рекомендуем их прочитать.

В этой статье мы хотим подробно рассказать о маленьких хитростях работы с Perl, касающихся необычного использования функций, которые могут пригодится всем, кто интересуется этим языком.

Как работают функции Perl?

В большинстве языков программирования описание функции выглядит примерно так:
function myFunction (a, b) { return a + b; }
А вызывается функция так:
myFunction(1, 2);
На первый взгляд всё просто и понятно. Однако вызов этой функции в следующем виде:
myFunction(1, 2, 3); … в большинстве случаев приведёт к ошибкам, связанным с тем, что в функцию передано неверное количество аргументов.

Функция в Perl может быть записана так:
sub my_sub($$;$) : MyAttribute { my ($param) = @_; }
Где $$;$ - это прототип, а MyAttribute - это атрибут. Прототипы и атрибуты будут рассмотрены далее в статье. А мы пока рассмотрим более простой вариант записи функции:
sub my_sub { return 1; }
Здесь мы написали функцию, которая возвращает единицу.

Но в этой записи не указано, сколько аргументов принимает функция. Именно поэтому ничего не мешает вызвать её вот так:
my_sub("Туземец", "Бусы", "Колбаса", 42);
И всё прекрасно выполняется! Это происходит потому, что в Perl передача параметров в функцию сделана хитро. Perl славится тем, что у него много так называемых «специальных» переменных. В каждой функции доступна специальная переменная @_, которая является массивом входящих параметров.

Поэтому внутри функции мы можем поместить входные параметры в переменные так:
my ($param) = @_;
Это работает и в случае нескольких параметров:
my ($param1, $param2, $param3) = @_;

Очень часто в функциях пишут следующее:
sub my_sub { my $param = shift; ... }
Дело в том, что в Perl многие функции при вызове без аргументов используют переменные по умолчанию. shift же по умолчанию достаёт данные из массива @_. Поэтому записи:
my $param = shift; … и
my $param = shift @_; … совершенно эквивалентны, но первая запись короче и очевидна для Perl-программистов, поэтому используется именно она.

Shift можно использовать и для получения нескольких параметров, в том числе комбинируя в одно списочное присваивание:
my ($one, $two, $three) = (shift, shift, shift);
Другая запись:
my ($one, $two, $three) = @_; … работает точно так же.

А теперь внимание! Грабли, на которые рано или поздно наступает каждый Perl-программист:
sub my_sub { my $var = @_; print $var; }
Если вызвать данную функцию как my_sub(1, 2, 3) в $var мы внезапно получим не 1, а 3. Это происходит потому, что в данном случае контекст переменной определяется как скалярный, а в Perl массив в скалярном контексте возвращает свой размер, а не первый элемент. Чтобы исправить ошибку, достаточно взять $var в скобки, чтобы контекст стал списочным. Вот так:
sub my_sub { my ($var) = @_ }
И теперь, как и ожидалось, при вызове my_sub(1, 2, 3) в $var будет 1.

Кроме того, в Perl параметры передаются по ссылке. Это значит, что мы можем внутри функции модифицировать параметры, которые в неё переданы.

Например:
my $var = 5; my_sub($var); print $var; sub my_sub { # вспоминаем, что доступ к элементам массива выполняется в скалярном контексте # т. е. доступ к нулевому элементу массива @arr будет выглядеть как $arr, то же самое и с # @_. $_++; # $_ - первый элемент массива @_. }
Результат будет 6. Однако в Perl можно сделать в каком-то роде «передачу по значению» вот так:
my $var = 5; my_sub($var); print $var; sub my_sub { my ($param) = @_; $param++; }
А вот теперь результат будет 5.

И последние два нюанса, которые очень важны. Perl автоматически возвращает из функции результат последнего выражения.

Возьмём код из предыдущего примера и немного его модифицируем:
my $var = 5; my $result = my_sub($var); print $result; sub my_sub { my ($param) = @_; ++$param; }
Это будет работать точно так же, как если бы в последней строке функции был явный возврат значения:
return ++$param;
Функция вернёт 6.

И ещё одна особенность: если в теле функции вызывается другая функция с использованием амперсанда и без скобок, то внутренняя функция получает на вход параметры той функции, в теле которой она вызывается. Т. е. массив @_ будет автоматически передан из внешней функции во внутреннюю. Это может привести к неочевидным багам.
use strict; use Data::Dumper; my_sub(1, 2, 3); sub my_sub { &inner; } sub inner { print Dumper \@_; }
Результат:
$VAR1 = [
1,
2,
3
];

Однако, если явно указать (с помощью пустых скобок), что функция вызывается без параметров, то всё в порядке:
sub my_sub { &inner(); }
И вывод будет выглядеть вот так:
$VAR1 = ;

Впрочем, вызовы функций с использованием амперсанда используются очень редко и в коде почти не встречаются.

Анонимные функции

Анонимные функции объявляются в месте использования и не получают уникального идентификатора для доступа к ним. При создании они либо вызываются напрямую, либо ссылка на функцию присваивается переменной, с помощью которой затем можно косвенно вызывать эту функцию.

Элементарное объявление анонимной функции в Perl:
my $subroutine = sub { my $msg = shift; printf "I am called with message: %s\n", $msg; return 42; }; # $subroutine теперь ссылается на анонимную функцию $subroutine->("Oh, my message!");
Анонимные функции можно и нужно использовать как для создания блоков кода, так и для замыканий, о которых речь дальше.

Замыкания

Замыкание - это особый вид функции, в теле которой используются переменные, объявленные вне тела этой функции.

В записи это выглядит как, например, функция, находящаяся целиком в теле другой функции.
# возвращает ссылку на анонимную функцию sub adder($) { my $x = shift; # в котором x - свободная переменная, return sub ($) { my $y = shift; # а y - связанная переменная return $x + $y; }; } $add1 = adder(1); # делаем процедуру для прибавления 1 print $add1->(10); # печатает 11 $sub1 = adder(-1); # делаем процедуру для вычитания 1 print $sub1->(10); # печатает 9
Замыкания использовать полезно, например, когда необходимо получить функцию с уже готовыми параметрами, которые будут в ней сохранены. Или же для генерации функции-парсера, колбеков.

Бесскобочные функции

На наш взгляд, это самый подходящий перевод термина parenthesis-less.

Например, print часто пишется и вызывается без скобок. Возникает вопрос, а можем ли мы тоже создавать такие функции?

Безусловно. Для этого у Perl есть даже специальная прагма - subs. Предположим, нам нужна функция, проверяющая значение переменной на истинность.
use strict; use subs qw/checkflag/; my $flag = 1; print "OK" if checkflag; sub checkflag { return $flag; }
Эта программа напечатает OK.

Но это не единственный способ. Perl хорошо продуман, поэтому, если мы реструктуризируем нашу программу и приведём её к такому виду:
use strict; my $flag = 1; sub checkflag { return $flag; } print "OK" if checkflag; …то результат будет тот же.

Закономерность здесь следующая - мы можем вызывать функцию без скобок в нескольких случаях:

  • используя прагму subs;
  • написав функцию ПЕРЕД её вызовом;
  • используя прототипы функций.
Обратимся к последнему варианту.

Прототипы функций


Зачастую разное понимание цели этого механизма приводит к холиварам с адептами других языков, утверждающих, что «у перла плохие прототипы». Так вот, прототипы в Perl не для жёсткого ограничения типов параметров, передаваемых функциям. Это подсказка для языка: как разбирать то, что передаётся в функцию.

Есть, к примеру, абстрактная функция, которая называется my_sub:
sub my_sub { print join ", ", @_; }
Мы её вызываем следующим образом:
my_sub(1, 2, 3, 4, 5);
Функция напечатает следующее:
1, 2, 3, 4, 5,

Получается, что в любую функцию Perl можно передать любое количество аргументов. И пусть сама функция разбирается, что мы от неё хотели.

Предполагается, что должен быть механизм контроля переданных в функцию аргументов. Эту роль и выполняют прототипы.

Функция Perl с прототипами будет выглядеть так:
sub my_sub($$;$) { my ($v1, $v2, $v3) = @_; $v3 ||= "empty"; printf("v1: %s, v2: %s, v3: %s\n", $v1, $v2, $v3); }
Прототипы функций записываются после имени функции в круглых скобках. Прототип $$;$ означает, что в качестве параметров необходимо присутствие двух скаляров и третьего по желанию, «;» отделяет обязательные параметры от возможных.

Если же мы попробуем вызвать её вот так:
my_sub(); …то получим ошибку вида:
Not enough arguments for main::my_sub at pragmaticperl.pl line 7, near "()"
Execution of pragmaticperl.pl aborted due to compilation errors.

А если так:
&my_sub(); …то проверка прототипов не будет происходить.

Резюмируем. Прототипы будут работать в следующих случаях:

  • Если функция вызывается без знака амперсанда (&). Perlcritic (средство статического анализа Perl кода), кстати говоря, ругается на запись вызова функции через амперсанд, то есть такой вариант вызова не рекомендуется.
  • Если функция написана перед вызовом. Если мы сначала вызовем функцию, а потом её напишем, при включённых warnings получим следующее предупреждение:
    main::my_sub() called too early to check prototype at pragmaticperl.pl line 4
Ниже пример правильной программы с прототипами Perl:
use strict; use warnings; use subs qw/my_sub/; sub my_sub($$;$) { my ($v1, $v2, $v3) = @_; $v3 ||= "empty"; printf("v1: %s, v2: %s, v3: %s\n", $v1, $v2, $v3); } my_sub();
В Perl существует возможность узнать, какой у функции прототип. Например:
perl -e "print prototype("CORE::read")"
Выдаст:
*\$$;$

Оверрайд методов

Оверрайд - часто довольно полезная штука. Например, у нас есть модуль, который писал некий N. И всё в нём хорошо, а вот один метод, допустим, call_me, должен всегда возвращать 1, иначе беда, а метод из базовой поставки модуля возвращает всегда 0. Код модуля трогать нельзя.

Пусть программа выглядит следующим образом:
use strict; use Data::Dumper; my $obj = Top->new(); if ($obj->call_me()) { print "Purrrrfect\n"; } else { print "OKAY:(\n"; } package Top; use strict; sub new { my $class = shift; my $self = {}; bless $self, $class; return $self; } sub call_me { print "call_me from TOP called!\n"; return 0; } 1;
Она выведет:
call_me from TOP called!
OKAY:(

И снова у нас есть решение.

Допишем перед вызовом $obj->call_me() следующую вещь:
*Top::call_me = sub { print "Overrided subroutine called!\n"; return 1; };
А ещё лучше, для временного оверрайда используем ключевое слово local:
local *Top::call_me = sub { print "Overrided subroutine called!\n"; return 1; };
Это заменит функцию call_me пакета Top в лексической области видимости (в текущем блоке).
Теперь наш вывод будет выглядеть так:
Overrided subroutine called!
Purrrrfect

Код модуля не меняли, функция теперь делает то, что нам надо.

На заметку: если приходится часто использовать данный приём в работе - налицо архитектурный косяк. Хороший пример использования - добавление вывода отладочной информации в функции.

Wantarray

В Perl есть такая полезная штука, которая позволяет определить, в каком контексте
вызывается функция. Например, мы хотим, чтобы функция вела себя следующим образом:
когда надо возвращала массив, а иначе - ссылку на массив. Это можно реализовать, и
к тому же очень просто, с помощью wantarray. Напишем простую программу для демонстрации:
#!/usr/bin/env perl use strict; use Data::Dumper; my @result = my_cool_sub(); print Dumper @result; my $result = my_cool_sub(); print Dumper $result; sub my_cool_sub { my @array = (1, 2, 3); if (wantarray) { print "ARRAY!\n"; return @array; } else { print "REFERENCE!\n"; return \@array; } }
Что выведет:
ARRAY!
$VAR1 = 1;
$VAR2 = 2;
$VAR3 = 3;
REFERENCE!
$VAR1 = [
1,
2,
3
];

Также хотелось бы напомнить про интересную особенность Perl. %hash = @аrray; В этом случае Perl построит хэш вида ($array => $array, $array => $array);

Посему, если применять my %hash = my_cool_sub(), будет использована ветка логики wantarray. И именно по этой причине wanthash нет.

AUTOLOAD

В Perl одна из лучших систем управления модулями. Мало того что программист может контролировать все стадии исполнения модуля, так ещё существуют интересные особенности, которые делают жизнь проще. Например, AUTOLOAD.

Суть AUTOLOAD в том, что когда вызываемой функции в модуле не существует, Perl ищет функцию AUTOLOAD в этом модуле, и только затем, если не находит, выбрасывает исключение о вызове несуществующей функции. Это значит, что мы можем описать обработчик ситуаций, когда вызывается несуществующая функция.

Например:
#!/usr/bin/env perl use strict; Autoload::Demo::hello(); Autoload::Demo::asdfgh(1, 2, 3); Autoload::Demo::qwerty(); package Autoload::Demo; use strict; use warnings; our $AUTOLOAD; sub AUTOLOAD { print $AUTOLOAD, " called with params: ", join (", ", @_), "\n"; } sub hello { print "Hello!\n"; } 1;
Очевидно, что функций qwerty и asdfgh не существует в пакете Autoload::Demo. В функции AUTOLOAD специальная глобальная переменная $AUTOLOAD устанавливается равной функции, которая не была найдена.

Вывод этой программы:
Hello!
Autoload::Demo::asdfgh called with params: 1, 2, 3
Autoload::Demo::qwerty called with params:

Генерация функций на лету

Допустим, нам нужно написать множество функций, выполняющих примерно одинаковые действия. Например, набор аксессоров у объекта. Написание подобного кода вряд ли кому-то доставит удовольствие:
sub getName { my $self = shift; return $self->{name}; } sub getAge { my $self = shift; return $self->{age}; } sub getOther { my $self = shift; return $self->{other}; }
Это Perl. «Лень, нетерпение, надменность» (Л. Уолл).

Функции можно генерировать. В Perl есть такая штука как тип данных typeglob. Наиболее точный перевод названия - таблица имён. Typeglob имеет свой сигил - «*».

Для начала посмотрим код:
#!/usr/bin/env perl use strict; use warnings; package MyCoolPackage; sub getName { my $self = shift; return $self->{name}; } sub getAge { my $self = shift; return $self->{age}; } sub getOther { my $self = shift; return $self->{other}; } foreach (keys %{*MyCoolPackage::}) { print $_." => ".$MyCoolPackage::{$_}."\n"; }
Вывод:
getOther => *MyCoolPackage::getOther
getName => *MyCoolPackage::getName
getAge => *MyCoolPackage::getAge

В принципе, глоб - это хэш с именем пакета, в котором он определен. Он содержит в качестве ключей элементы модуля + глобальные переменные (our). Логично предположить, что если мы добавим в хэш свой ключ, то этот ключ станет доступен как обычная сущность. Воспользуемся генерацией функций для генерации данных геттеров.

И вот что у нас получилось:
#!/usr/bin/env perl use strict; use warnings; $\ = "\n"; my $person = Person->new(name => "justnoxx", age => "25", other => "perl programmer",); print "Name: ", $person->get_name(); print "Age: ", $person->get_age(); print "Other: ", $person->get_other(); package Person; use strict; use warnings; sub new { my ($class, %params) = @_; my $self = {}; no strict "refs"; for my $key (keys %params) { # __PACKAGE__ равен текущему модулю, это встроенная # волшебная строка # следующая строка превращается в, например: # Person::get_name = sub {...}; *{__PACKAGE__ . "::" . "get_$key"} = sub { my $self = shift; return $self->{$key}; }; $self->{$key} = $params{$key}; } bless $self, $class; return $self; } 1;
Эта программа напечатает:
Name: justnoxx
Age: 25
Other: perl programmer

Атрибуты функций

В Python есть такое понятие как декоратор. Это такая штуковина, которая позволяет «добавить объекту дополнительное поведение».

Да, в Perl декораторов нет, зато есть атрибуты функций. Если мы откроем perldoc perlsub и посмотрим на описание функции, то увидим любопытную запись:
sub NAME(PROTO) : ATTRS BLOCK
Таким образом, функция с атрибутами может выглядеть так:
sub my_sub($$;$) : MyAttr { print "Hello, I am sub with attributes and prototypes!"; }
Работа с атрибутами в Perl - дело нетривиальное, потому уже довольно давно в стандартную поставку Perl входит модуль Attribute::Handlers.

Дело в том, что атрибуты из коробки имеют довольно много ограничений и нюансов работы, так что, если кому-то интересно, можно обсудить в комментариях.

Допустим, у нас есть функция, которая может быть вызвана только в том случае, если пользователь авторизован. За то, что пользователь авторизован отвечает переменная $auth, которая равна 1, если пользователь авторизован, и 0, если нет. Мы можем сделать следующим образом:
my $auth = 1; sub my_sub { if ($auth) { print "Okay!\n"; return 1; } print "YOU SHALL NOT PASS!!!1111"; return 0; }
И это приемлемое решение.

Но может возникнуть такая ситуация, что функций будет становиться больше и больше. А в каждой делать проверку будет всё накладнее. Проблему можно решить с помощью атрибутов.
use strict; use warnings; use Attribute::Handlers; use Data::Dumper; my_sub(); sub new { return bless {}, shift; } sub isAuth: ATTR(CODE) { my ($package, $symbol, $referent, $attr, $data, $phase, $filename, $linenum) = @_; no warnings "redefine"; unless (is_auth()) { *{$symbol} = sub { require Carp; Carp::croak "YOU SHALL NOT PASS\n"; }; } } sub my_sub: isAuth { print "I am called only for auth users!\n"; } sub is_auth { return 0; }
В данном примере вывод программы будет выглядеть так:
YOU SHALL NOT PASS at myattr.pl line 18. main::__ANON__() called at myattr.pl line 6

А если мы заменим return 0 на return 1 в is_auth, то:
I am called only for auth users!

Не зря атрибуты представлены в конце статьи. Для того чтобы написать этот пример, мы воспользовались:

  • анонимными функциями
  • оверрайдом функций
  • специальной формой оператора goto
Несмотря на довольно громоздкий синтаксис, атрибуты успешно и активно применяются, например, в веб-фреймворке Catalyst. Однако, не стоит забывать, что атрибуты, всё-таки, являются экспериментальной фичей Perl, а потому их синтаксис может меняться в следующих версиях языка.

Статья написана в соавторстве и по техническому материалу от Дмитрия Шаматрина (@justnoxx) и при содействии программистов REG.RU: Тимура Нозадзе (@TimurN), Виктора Ефимова (@vsespb), Полины Шубиной (@imagostorm), Andrew Nugged (@nugged)

Встпвляет пространство имен одного модуля в другой. Это не встроенная функция, а всего лищь метод, наследуемый от модуля (параметр МОДУЛЬ), которому необходимо экспортировать свои имена (параметр СПИСОК) в другой модуль.

Import МОДУЛЬ СПИСОК

local

Функция local() используется для объявления и инициализации одной или нескольких переменных:

Local EXPR local ($myvar, , %myhash); local $pi = 3.14159; local ($pi, $exp) = (3.14159, 2.71828);

но, в отличие от функции my() она создает не локальные переменные, а временные значения для глобальных переменных внутри:

  • подпрограммы;
  • заключенного в фигурные скобки блока операторов;
  • выражения, пареданного на выполнение функции eval();
  • файла;

В зависимости от того, в каком месте вызвана для объявления переменных сама функция local(). Если функция local() применяется для описания нескольких переменных, они должны быть заключены в скобки. Если глобальня перемнная, объявленная при помощи этой функции, ранее встречалась до объявления и имела некоторое значение, то это значение сохраняется в скрытом стеке и восстанавливается после выхода соответственно из подпрограммы, блока, функции eval() или файла. Переменная, объявленная при помощи функции local(), или, точнее, ее временное значение, доступна для любой функции, вызванной внутри подпрограммы, блока, функции eval() или файла, в которых сделано объявление. Такую переменную называют динамической, а ее область видимости - динамической областью видимости. В названии отражается тот факт, что область видимости переменной динамически изменяется с каждым вызовом функции, получающей доступ к этой переменной.

Пример:

my

Функция my() используется для объявления одной или нескольких переменных локальными:

и ограничивает их область действия:

  • подпрограммой;
  • заключенным в фигурные скобки блоком операторов;
  • выражением, пареданным на выполнение функции eval();
  • файлом, в зависимости от того, в каком месте вызвана для объявления переменных сама функция my().

Если выражение EXPR содержит список переменных, то он должен быть заключен в скобки:

My ($myvar, @mylist, %myhash);

Одновременно с объявлением переменные могут быть инициализированны:

My $pi = 3.14159; my ($pi, $exp) = (3.14159, 2.71828);

Переменные, объявленные при помощи функции my(), доступны в своей области действия только для подпрограмм, определенных в этой области. Для подпрограмм, определенных за ее пределами, они недоступны. Такие переменные называются лексическими, а саму область видимости - лексической или статической областью видимости.

Пример:

Sub f1{ local ($x) = "aaaa"; my($y) = "bbbb"; print("f1: x = $xn"); print("f1: y = $ynn"); f2(); print("f1: x = $xn"); print("f1: y = $ynn"); } sub f2{ print("f2: x = $xn"); print("f2: y = $ynn"); $x = "cccc"; $y = "dddd"; print("f2: x = $xn"); print("f2: y = $ynn"); } f1;

Результатом выполнения данного примера будет следующий вывод:

F1: x = aaaa f1: y = bbbb f2: x = aaaa f2: y = f2: x = cccc f2: y = dddd f1: x = cccc f1: y = bbbb

Как видно из приведенного результата, функция f2() не имеет доступа к переменной $y, объявленной при помощи функции my() внутри функции f1(), и,напртив, имеет доступ к переменной $x, объявленной внутри f1() при помощи функции local().

package

Определяет отдельное глобальное пространство имен (пакет): все неопределенные динамические идентификаторы (включая те, которые объявлены через local(), но не my()) будут храниться в нем. Для доступа к ним вне пакета следует указывать префикс, представляющий имя пакета с последующими двумя символами двоеточий "::". Область видимости переменных пакета распространяется до конца блока операторов, в котором расположен пакет или до нового объявления пакета. Если опущено имя пакета, то предписывает, чтобы все индентификаторы были определены, включая имена функций.

Package [ИМЯ_ПАКЕТА]

use

Загружает модуль во время компиляции; если модуль не доступен, то компиляция всей программы прекращается.

Use МОДУЛЬ СПИСОК use МОДУЛЬ use МОДУЛЬ ВЕРСИЯ СПИСОК use ВЕРСИЯ

¦ Конверторы интерфейса Gigabit (Gigabit interface converters – GBIC) поддерживают последовательную и параллельную трансляцию передаваемых данных. Конверторы GBIC предоставляют возможность «горячего» подключения, т.е. включение/выключение GBIC не влияет на работу других портов. Конверторами используется 20-битовый параллельный интерфейс.

Модули линий Gigabit (Gigabit link modules – GLM) предоставляют функции, аналогичные GBIC, но для своей установки требуют отключения устройства. С другой стороны, они несколько дешевле, чем GBIC.

Адаптеры интерфейса носителя (Media Interface Adapters) используются для преобразования сигналов между медным и оптическим носителем и наоборот. Адаптеры интерфейса носителя обычно используются в адаптерах шины, но могут применяться и на коммутаторах и концентраторах.

Адаптеры малого формфйктора (Small Form Factor Adapters – SFF) позволяют размещать большее количество разъемов различных интерфейсов на плате определенного размера.


4.7.4 Устройства взаимодействия

Устройства взаимодействия соединяют между собой компоненты сетей хранения данных. К ним относятся различные устройства, начиная от дешевых концентраторов Fibre Channel и заканчивая дорогими, высокопроизводительными и управляемыми коммутаторами связной архитектуры. Эти устройства рассматриваются в разделах 4.7.4.1–4.7.4.3.


4.7.4.1 Концентраторы кольца Fibre Channel с разделением доступа

Концентраторы FC-AL представляют собой бюджетный вариант для подключения нескольких узлов Fibre Channel (устройств хранения данных, серверов, компьютерных систем, других концентраторов и коммутаторов) в кольцевую конфигурацию. Обычно в концентраторах предоставляется от 8 до 16 портов. Концентратор может поддерживать различные среды передачи, например медные или оптические.

Концентраторы Fibre Channel – это пассивные устройства, т.е. любое другое устройство в кольце не может обнаружить их присутствия. Концентраторы обеспечивают следующие возможности:

внутренние соединения, которые позволяют любому порту подключаться к любому другому порту;

возможность обхода порта, к которому подключено неправильно работающее устройство.

Самая большая проблема в работе портов связана с тем, что в текущий момент времени они могут поддерживать только одно подключение Fibre Channel. На рис. 4.7 показано, что, если порт 1 получил управление для установки сеанса с портом 8, ни один другой порт не сможет передавать данные, пока установленный сеанс не завершится.

Концентраторы могут быть подключены к коммутаторам связной архитектуры Fibre Channel (они рассматриваются в разделе 4.7.4.3) без модификации. Кроме того, можно создавать каскад концентраторов, соединив два концентратора кабелем.

Концентраторы FC-AL занимают лидирующее положение на рынке Fibre Channel, но в процессе снижения стоимости коммутаторы связной архитектуры Fibre Channel становятся все более популярными.

Концентраторы FC-AL создаются такими компаниями, как Gadzoox Networks, Emulex и Brocade.


4.7.4.2 Коммутаторы кольца Fibre Channel с разделением доступа

Самое значительное преимущество коммутаторов FC-AL

перед концентраторами состоит в одновременной поддержке нескольких подключений, тогда как концентраторы поддерживают только одно подключение в текущий момент времени (рис. 4.8).

Рис. 4.7. Концентратор Fibre Channel

Рис. 4.8. Коммутатор Fibre Channel


Возможность одновременной поддержки нескольких подключений связана с определенными сложностями. Устройства, подключенные к коммутатору кольца, даже не «подозревают» о своей роли. Коммутаторы кольца участвуют как в передаче данных, так и в адресации кольца. Ниже приводится дополнительная информация по этому вопросу, а также рассматривается роль коммутаторов в сетях хранения данных и методы, с помощью которых поставщики добавляют новые функции к своим продуктам.


Коммутаторы кольца и передача данных

Сервер, который намерен получить доступ к устройству хранения данных, должен отправить арбитражный запрос на управление кольцом. В нормальном кольце FC-AL на базе концентратора каждое устройство получает

арбитражный пакет до его возвращения адаптеру шины сервера, благодаря чему сервер получает контроль над кольцом. Коммутатор кольца отправит ответ об успешном получении управления немедленно, не отправляя запросы другим узлам. На этом этапе адаптер шины отправит базовый пакет Open, предназначенный для порта устройства хранения, который будет передан коммутатором кольца. Если порт в это время не выполняет передачи данных, особых проблем не должно возникнуть. В противном случае возможно появление конфликтных ситуаций. Для решения этой проблемы коммутатор кольца должен предоставить буфера для временного хранения кадров, предназначенных для порта 7. Некоторые поставщики коммутаторов предоставляют для этих целей 32 буфера на каждый порт.


Коммутаторы кольца и адресация FC-AL

Концентраторы FC-AL не играют роли в назначении адресов устройствам, а только передают базовые кадры адресов по кольцу. То же можно сказать и о большинстве коммутаторов. Однако некоторые устройства могут настаивать на получении определенного адреса. Некоторые концентраторы имеют возможность управлять порядком инициализации портов, что позволяет определенному порту инициализироваться первому, после чего устройство будет подключено к требующемуся порту.


Коммутаторы и инициализация кольца

Протокол FC-AL требует повторной инициализации кольца при подключении, отключении или повторной инициализации устройства. Такая инициализация кольца может привести к нарушению существующей связи между другими двумя устройствами. Некоторые производители коммутаторов предоставляют возможность выборочно экранировать и передавать пакеты LIP (Loop Initialization Primitives). Эта операция предназначена для минимизации проблем, сокращения времени повторной инициализации кольца и по возможности сохранения существующих сеансов передачи данных. В то же время необходимо обеспечить уникальность адресов устройств.

Если все устройства принимают участие в повторной инициализации кольца, дублирования адресов не происходит, так как устройства «защищают» свои адреса. Но, если некоторые устройства не принимают участия в повторной инициализации кольца, необходимо предотвратить назначение уже распределенных адресов устройствам, принимающим участие в повторной инициализации кольца. Уникальность адресов обеспечивается дополнительной логикой коммутатора кольца. При добавлении устройства хранения пакет LIP должен быть отправлен на сервер, однако LIP не требуется передавать устройствам хранения, которые никогда не устанавливают связь с другими устройствами хранения данных.

Некоторые устройства хранения могут устанавливать связь непосредственно с другими устройствами хранения, что используется для резервного копирования данных. Дополнительная информация об операциях копирования приводится в главе 5.


Коммутаторы кольца и связная архитектура

Если все устройства в кольце «знают» о связной архитектуре, коммутатор кольца передает обычным образом необходимые кадры, например кадры Fabric Login. Если устройства в кольце не поддерживают связную архитектуру, коммутатор кольца должен самостоятельно выполнять достаточно большой объем работы.

Коммутаторы кольца некоторых поставщиков не поддерживают каскадирование. Кроме того, некоторым коммутаторам кольца требуется обновление прошивки перед подключением к коммутаторам связной архитектуры. Ряд коммутаторов следует модернизировать для полной поддержки связной архитектуры перед их подключением к SAN.

Коммутаторы FC-AL производятся такими компаниями, как Brocade, McDATA, Gadzoox Networks, Vixel и QLogic.


4.7.4.3 Коммутаторы связной архитектуры Fibre Channel

Коммутаторы связной архитектуры Fibre Channel (Fibre Channel Fabric Switches – FC-SW) обеспечивают несколько выскоскоростных сеансов связи одновременно со всеми устройствами. На данный момент основные коммутаторы поддерживают быстродействие порядка 1 Гбит/с, в то время как скорость в 2 Гбит/с также перестает быть диковинкой. В основном коммутаторы связной архитектуры в пересчете на один порт стоят дороже, чем концентраторы и коммутаторы FC-AL, но они предоставляют намного больше функциональных возможностей.

Коммутаторы связной архитектуры более эффективны в сравнении с концентраторами и коммутаторами FC-AL. Например, коммутаторы предоставляют специальные службы, описанные выше, обеспечивают управление потоком с помощью базовых пакетов управления, а также, что гораздо важнее, некоторые коммутаторы способны эмулировать функции FC-AL для обеспечения обратной совместимости с более старыми устройствами.

Некоторые коммутаторы связной архитектуры поддерживают маршрутизацию без буферизации. Суть ее в том, что при получении заголовка кадра коммутатор быстро находит заголовок точки назначения, пока кадр все еще принимается. Преимущество такого подхода – снижение задержек при доставке кадра и отсутствие необходимости хранения содержимого кадра в памяти буфера. А недостаток заключается в немедленной передаче всех кадров, включая поврежденные.

Коммутаторы связной архитектуры играют важную роль в безопасности сетей хранения данных на основе Fibre Channel, что описывается более подробно в главе 7.


4.7.4.4 Сравнение трех устройств подключения

В табл. 4.5 приведены функциональные возможности и различия между тремя типами устройств Fibre Channel.


4.7.4.5 Мосты и маршрутизаторы

Как в этой главе, так и во всей книге термины мосты (bridges) и маршрутизаторы (routers) не относятся к традиционным мостам Ethernet и маршрутизаторам IP. В данном случае под мостами и маршрутизаторами подразумеваются устройства для Fibre Channel, а не для сетевых протоколов 2-го и 3-го уровней.

Мосты –¦ это устройства, обеспечивающие взаимодействие между Fibre Channel и устаревшими протоколами, например SCSI. Мосты Fibre Channel- SCSI позволяют сохранить существующие инвестиции в устройства хранения SCSI. Такие мосты поддерживают интерфейсы SCSI и Fibre Channel и преобразуют данные двух протоколов. Таким образом, новый сервер с установленным адаптером шины Fibre Channel может получить доступ к существующим устройствам хранения SCSI. Мосты предоставляют интерфейс между параллельной шиной SCSI и интерфейсом Fibre Channel. Маршрутизаторы обладают аналогичными возможностями, но для нескольких шин SCSI и интерфейсов Fibre Channel. Маршрутизаторы систем хранения данных, или «интеллектуальные» мосты, предоставляют такие дополнительные возможности, как маскировка и отображение LUN, а также поддерживают команды SCSI Extended Сору. В качестве устройств, передающих данные, маршрутизаторы применяют команды Extended Сору для использования библиотеками хранения, что позволяет копировать данные между указанным целевым устройством и подключенной библиотекой. Эта функция также называется независимым резервным копированием (без сервера).

В качестве примера производителей маршрутизаторов и мостов можно привести такие компании, как Crossroads Systems, Chaparral Network Storage, Advanced Digital Information Corporation (ADIC после приобретения Path- light) и MTI.





4.8 Методы управления Fibre Channel

В предыдущих разделах рассматривались аппаратные элементы, формирующие сети хранения данных. В работе SAN также участвует немало различных программ, в основном предназначенных для управления, обеспечения безопасности, резервного копирования и восстановления данных. В разделах 4.8.1 и 4.8.2 рассматривается ряд концепций, необходимых для управления SAN и обеспечения безопасности данных. По сути, эти концепции предоставляют собой «сердце» SAN.

В ситуации, когда одна сеть содержит несколько компьютеров и единиц хранения данных, желательно ограничить влияние некоторых компьютеров (в терминологии Fibre Channel они называются узлами) до определенных подсистем хранения и некоторых единиц в рамках этих подсистем. Это имеет особый смысл в том случае, когда узел работает под управлением Windows NT, которая требует монтирования каждого обнаруженного устройства. С другой стороны, у UNIX есть таблица монтирования, благодаря чему монтируются только устройства, непосредственно указанные в таблице. Даже при использовании узлов под управлением UNIX желательно ограничить доступ из соображений обеспечения безопасности и для снижения вероятности повреждения данных. Доступ может быть ограничен тремя различными типами функций отображения и зонирования.

Базовая функция, реализованная в рамках узла; возможно, средствами программного драйвера адаптера шины.

Функция коммутатора.

Функция на уровне подсистемы хранения данных.


4.8.1 Зонирование

Термин зонирование связан с коммутаторами. Зонирование позволяет одним портам коммутатора подключаться только к заранее определенным портам. В некоторых случаях зонирование может ограничивать распространение управляющих кадров Fibre Channel; например, при появлении в кольце нового устройства хранения можно ограничить распространение кадра LIP среди других устройств.

С функциональной точки зрения зонирование дает возможность некоему компьютеру непосредственно подключаться к определенной подсистеме хранения данных. Недостаток такого подхода состоит в предоставлении всех ресурсов SAN для одного компьютера, который обычно не в состоянии полностью их использовать. В частности, зонирование не позволяет совместно загружать канал доступа сети или применять ресурсы подсистемы хранения данных.

Рис. 4.9. Зонирование SAN


Зонирование можно воспринимать в качестве аналога конфигурирования порта IP для маршрутизатора с поддержкой брандмауэра. Еще одним примером может быть настройка виртуальных локальных сетей (VLAN) в существующей физической локальной сети. В виртуальной локальной сети только некоторые устройства «видят» друг друга, даже если в той же физической локальной сети находятся и другие устройства. Точно так же зонирование ограничивает возможности компонентов SAN (особенно инициаторов), предоставляя ограниченные данные об определенных единицах хранения и возможность доступа к ним, даже если в этой же физической сети хранения данных размещены и другие устройства хранения.

На рис. 4.9 демонстрируется концепция зонирования. Сеть хранения данных имеет три сервера и три единицы хранения. Различными оттенками указываются разные зоны.

Имена LUN могут совместно использоваться программным обеспечением файловой системы SAN. В этом программном обеспечении один или несколько серверов работают как серверы метаданных. Программное обеспечение устанавливается на клиентском компьютере (на компьютере, который желает получить доступ к файлам в сети хранения данных) и на сервере метаданных. Метаданные предоставляют клиентскому компьютеру информацию для отображения логического смещения в файле на физический номер блока указанного устройства. Это позволяет клиентскому компьютеру непосредственно получать доступ к файлу через SAN, без переноса данных через сервер. При достаточно грамотной организации обычные разрешения для файлов на

клиентском компьютере будут относиться и к файлам, хранящимся удаленно, что не требует от администратора дополнительных действий по настройке разрешений на совместный доступ к файлам.

Можно определить несколько зон, причем один узел имеет возможность входить в несколько зон одновременно; таким образом, некоторые зоны будут перекрываться. Зонирование выполняется несколькими способами.

Зонирование по номеру порта. Преимущество такого подхода – эффективность. Если устройство, подключенное к порту, заменено другим устройством, повторная настройка не потребуется.

Зонирование по имени WWN. Осуществляется путем указания имен WWN, которые входят в одну зону. Некоторые WWN могут быть указаны в нескольких зонах. Преимущество состоит в безопасности, которая, однако, достигается за счет эффективности. Изменения в конфигурации могут потребовать перезагрузки сервера.

Программное зонирование. Проводится средствами сервера имен (программного обеспечения), который выполняется на коммутаторе. Для программного зонирования могут использоваться номера портов, WWN или комбинация этих параметров. Сервер имен содержит базу данных, в которой хранятся WWN, номера портов и идентификаторы зон.

Аппаратное зонирование. Осуществляется с помощью таблицы маршрутизации, которая хранится на коммутаторе. Аппаратное зонирование выполняется на основе WWN и не принимает во внимание номера портов.


4.8.2 Маскировка LUN

Ресурсы хранения могут быть «разделены» на несколько вложенных единиц (субъединиц), которые называются номером логического устройства (logical unit number – LUN). Стандарт SCSI-2 поддерживает до 64 LUN на одно устройство.

С функциональной точки зрения маскировка LUN позволяет определенному компьютеру получить доступ к конкретной субъединице на некой системе хранения данных. Однако гораздо важнее то, что с помощью этого способа можно запретить доступ к определенным LUN для некоторых компьютеров или серверов. Маскировка LUN дает возможность совместно использовать ресурсы хранилищ данных и (неявно) пропускную способность сети, однако непосредственно LUN совместно использоваться не может. Для совместного использования одного LUN несколькими компьютерами необходима файловая система с дополнительными возможностями, которая описана в главе 6.

Маскировка LUN необходима для гарантирования целостности данных в среде SAN. Обратите внимание: маскировка LUN – это средство обеспечения безопасности на уровне дисков, но не обязательно на уровне файлов. В последнем случае (на уровне файлов) потребуется дополнительное программное обеспечение.

Маскировка LUN предоставляет дополнительные возможности, в частности номера LUN могут быть переназначены другим компьютерам. Существует несколько способов обеспечения маскировки LUN. Каждый способ обладает своими достоинствами и недостатками. Обычно, маскировка выполняется средствами:

аппаратного обеспечения адаптера шины;

аппаратного обеспечения коммутатора Fibre Channel;

аппаратного обеспечения устройства хранения Fibre Channel;

программного обеспечения узла.

Эти варианты рассматриваются в разделах 4.8.2.1–4.8.2.4.


4.8.2.1 Маскировка LUN средствами BIOS адаптера шины

В BIOS адаптера шины осуществляется маскировка всех LUN, которые не отображены в таблице BIOS адаптера шины. Таким образом, узел (с установленным адаптером шины) попросту не «замечает» существования LUN, которые он и не должен «видеть».

Недостаток такого метода состоит в необходимости проведения корректной настройки; кроме того, метод не обязателен к применению. Все системы, адаптеры шины которых настроены неправильно или не поддерживают описываемую функцию, могут получить доступ к тем LUN, к которым доступ на самом деле нежелателен. Еще одна проблема заключается в сложности динамического управления и перенастройки подобных систем.


4.8.2.2 Маскировка LUN коммутаторами Fibre Channel

Коммутаторами Fibre Channel зонирование проводится достаточно просто. Входящий пакет передается или не передается дальше, что зависит от адресов исходного порта и порта назначения. Маскировка LUN возлагает дополнительную нагрузку на коммутаторы Fibre Channel, поскольку коммутатору приходится проверять первые 64 байта каждого пакета данных. Это приводит к снижению производительности большинства коммутаторов Fibre Channel, поэтому описываемая функция обычно не реализуется.


4.8.2.3 Маскировка LUN контроллерами подсистем хранения данных Fibre Channel и маршрутизаторами

Этот метод маскировки LUN является принудительным для подключенных узлов или требует от узла минимального участия. Маскировка LUN реализуется контроллером подсистемы хранения данных или маршрутизатором (с помощью соответствующей прошивки). Эти устройства настроены на поддержку таблицы имен WWN адаптера шины, отображённых на номера LUN, к которым им (контроллеру или маршрутизатору) разрешен доступ. Значительное преимущество такого подхода заключается в формировании конфигурации, независимой от промежуточных коммутаторов или концентраторов.

Недостаток метода заключается в закрытой реализации этой технологии каждым поставщиком и сложности создания единой консоли управления для перенастройки или даже получения информации о текущих параметрах, хотя каждый поставщик предоставляет интерфейсы для управления связками WWN-LUN.

К поставщикам систем, поддерживающим эту технологию, относятся Crossroads Systems, EMC, Dot Hill и HP (в продуктах Storage Works). Поставщики присваивают реализации технологии собственные названия; например, компания Crossroads называет это Access Controls, а компания HP в продуктах StorageWorks выбрала название Selective Storage Presentation.


4.8.2.4 Маскировка LUN программным обеспечением узла

Маскировка LUN выполняется. программным обеспечением узла, в частности кодом драйвера устройства. Код должен работать в режиме ядра, так как основная идея заключается в том, чтобы предотвратить доступ операционной системы к LUN, а операционная система сделает"это еще до запуска первого приложения пользовательского режима.

Такая маскировка может выполняться в виде функции операционной системы или вне системы. За неимением конкретного решения от Microsoft некоторые поставщики добавили необходимый код в драйвер адаптеров шины. Обычно драйвер выдает команду Report LUNs каждому устройству, подключенному к шине, и перед предоставлением списка LUN системе Windows NT драйвер «вырезает» LUN из списка на основе дополнительно запрошенных данных (например, информации системного реестра Windows NT), таким образом «скрывая» некоторые LUN от Windows.

Основная проблема такого метода – необязательная настройка, а следовательно, необходимость частичного участия узла в процессе маскировки LUN. Это означает, что компьютеры, не имеющие модифицированного драйвера адаптера шины, не принимают участия в маскировке LUN. Кроме того, присутствуют и проблемы масштабирования, так как в особенно больших сетях хранения данных сложно настроить каждый сервер и каждый адаптер шины сервера. Что касается преимуществ, то LUN может эффективно использоваться несколькими серверами.

Описываемая функция реализуется в продуктах компаний Emulex, Dell и JNI.


4.8.2.5 Маскировка LUN и будущее Windows NT

На данный момент существует информация, что Microsoft работает над реализацией возможностей маскировки LUN в драйвере порта. Тем не менее такая возможность отсутствует в Windows Server 2003. Преимущество использования драйвера порта состоит в постоянном присутствии драйвера. порта в памяти, поэтому время, в течение которого компьютер не будет принимать участие в маскировке LUN, существенно снижается. Вероятность загрузки неправильного драйвера порта намного ниже, чем вероятность загрузки неправильного драйвера порта и мини-порта. Судя по предварительным прогнозам, если описываемая функция будет реализована в Windows, администратор получит возможность самостоятельно определять и изменять список LUN, видимых для сервера; при этом список может быть изменен временно. В последнем случае изменения не будут сохраняться после перезагрузки сервера.

4.9 Обеспечение взаимодействия устройств Fibre Channel

Призыв «Покупатель, берегись!» хорошо описывает состояние взаимодействия устройств в мире Fibre Channel.

Можно сказать, что большинство проблем во взаимодействии конфигураций FC-AL связаны с устройствами хранения, адаптерами шины, коммутаторами FC-AL и поставщиками маршрутизаторов. Поставщики устройств проводят серьезное тестирование своих продуктов, но, хотя теоретически взаимодействие с другими устройствам и должно быть гарантировано, на практике для получения результата требуется немало дополнительного тестирования и настроек различных параметров. Рекомендуется использовать конфигурации, которые были протестированы поставщиком или продавцом готовых решений SAN.

Наибольшая проблема состоит в отсутствии гарантированного соответствия промышленным стандартам. Более того, даже соответствие стандартам также не обеспечивает 100%-ного взаимодействия.

Поставщики готовых решений, такие, как IBM, HP и EMC» создают лаборатории для тестирования взаимодействия различных устройств и проводят собственную сертификацию. До определенной степени другие поставщики поступают аналогично. Рекомендуется использовать именно такие сертифицированные решения, что позволяет избежать проблем, часто возникающих при добавлении новых, не сертифицированных поставщиком устройств.

Хотя немало сетей хранения данных на основе Fibre Channel обеспечивают быстродействие 1 Гбит/с, в последнее время в продаже появились устройства, поддерживающие скорость 2 Гбит/с. Новые устройства – новые проблемы. В стандартах, которым следуют производители, поддерживается скорость 2 Гбит/с, однако устройства автоматически переходят на скорость 1 Гбит/с, если на этой скорости работают другие устройства в сети. Дело в том, что сети хранения данных на базе Fibre ^ Channel должны работать на скорости самого медленного устройства в сети. Таким образом, даже единственное устройство, работающее на скорости 1 Гбит/с, заставит всю сеть хранения данных работать на этом уровне быстродействия.

4.10 Сложности практической реализации

Сети хранения данных на основе Fibre Channel эмулируют прямое подключение устройства хранения данных к серверу, даже если устройство на самом деле подключено через коммутатор. Таким образом, в контексте Windows доступ к устройствам Fibre Channel осуществляется с помощью драйверов SCSIPort или Storport, описанных в главе 2. Таким образом, особенности работы с хранилищем, подключенным непосредственно к серверу (DAS), имеют отношение и к SAN.

Новая модель драйверов Storport предоставляет массу функциональных возможностей, включая оптимизацию ввода-вывода и управление пропускной способностью сети, однако системные администраторы и ответственные лица в информационных отделах компаний должны обратить внимание на тот факт, что модель драйверов Storport поддерживается исключительно в Windows Server 2003. Принявшим решение об использовании платформы Windows стоит изучить планы поставщика устройств хранения данных относительно перехода на модель Storport. В то же время необходимо обратить внимание на реализацию поддержки этих устройств на базе платформы Windows 2000, включая подробности реализации драйвера устройства. Это особенно важно для определения адекватности пропускной способности устаревающей модели драйверов SCSIPort, если поставщик будет продолжать ее применение. Кроме того, необходимо узнать, предоставляет ли поставщик собственную архитектуру SAN, без модели драйверов SCSIPort, а также сертифицировано ли это решение и поддерживается ли оно всеми заинтересованными сторонами. Наконец, обратите внимание на планы поставщика по переходу на модель драйверов Storport для Windows Server 2003.

Маскировка LUN на данный момент не поддерживается в продаваемых версиях Windows, причем выпуск Windows Server 2003 не изменил ситуации. Прежде чем приобретать новое программное и аппаратное обеспечение, выясните, какую технологию использует поставщик для реализации маскировки LUN и насколько она подходит для работы в среде Windows.

4.11 Резюме

Сети хранения данных Fibre Channel составляют существенную часть корпоративных подсистем хранения данных. Технология Fibre Channel может внедряться в виде недорогих конфигураций на основе кольца или на базе набирающей популярность топологии коммутируемой связной архитектуры.

Операционная система Windows Server 2003 поддерживает устройства Fibre Channel с помощью драйвера Storport, предоставляемого поставщиком аппаратного обеспечения. Поставщик вместо этого может предоставить ми- ни-драйвер порта SCSI, но в таком случае преимущества драйвера Storport (например, повышенная производительность и обработка ошибок) окажутся недоступными для пользователей. Операционная система Windows 2000 и предыдущие ее версии поддерживают устройства Fibre Channel посредством мини-драйвера SCSIPort, предоставляемого поставщиками аппаратного обеспечения.

Несмотря на то что Windows NT поддерживает технологию маскировки LUN и зонирования, базовая поддержка маскировки LUN в Windows NT отсутствует. Маскировка LUN в Windows NT может быть реализована в драйвере от поставщика аппаратного обеспечения.

Примечания:

ISO - International Organization for Standardization (Международная организация по стандартизации);

OSI - Open System Interconnection (взаимодействие открытых систем).

В настоящий момент существует несколько различных физических стандартов, и тот факт, что используется лишь три базовых типа кабелей (медные, одно- и многомодовые), не означает наличия трех типов физических разъемов. Кроме того, эти типы применяются и в других интерфейсах, например Gigabit Ethernet.

Прежде чем говорить об аппаратном обеспечении и SAN, нужно всё-таки начать с того, что из себя SAN представляет в принципе, откуда он появился и почему.

Когда то давно, на заре компьютерной эры, внешние устройства хранения обычно подключались напрямую к серверам (DAS - Direct-attached storage), используя SCSI, но из-за крайне стремительного роста требования к системам хранения данный подход стал слишком неэффективным. Для изменения конфигурации хранилища, подключенного по технологии DAS требовало физического отключения сервера, построение отказоустойчивых систем то же было затруднительно ввиду необходимости иметь физическое подключение всех серверов ко всем устройствам хранения, а жёсткие ограничения по максимальному расстоянию между устройствами делали подобные расширения порой слишком сложными, да и производительность SCSI оставляла желать лучшего. Изменение подхода к подключению внешних хранилищ позволило получить следующие преимущества:

  • Изменение конфигураций хранилищ не затрагивает работу серверов и сервисов
  • Расстояние между устройствами позволило строить катастрофоустойчивые хранилища, расположенные на удалённых площадках
  • Любой сервер может получить доступ к любому устройству хранения в SAN сети

Обычно говоря SAN подразумевают сети на безе протокола Fibre Channel, но стоит отметить что протокол iSCSI позволяет строить аналогичные по своим характеристикам сети, основанные на IP сетях. Изначально, переход от SCSI к Fiber Channel был обусловлен желанием увеличить расстояние подключения, а не пропускную способность. Первая версия протокола, появившаяся в 1997 году, предоставляла скорость в 1Gb/s. Каждая новая версия прокола, постоянно "удваивает" скорость предыдущего поколения. На данный момент, актуальным является 6 поколение протокола, работающего на скорости 32/128Gb/s.

Fibre channel, как сетевой протокол, состоит из нескольких уровней:
FC-0 Физический : в котором описывается среда передачи данных, характеристики кабелей, трансиверов, HBA. Физические и электрические характеристики, скорость передачи данных.
FC-1 Кодирование : описывает как данные будут кодироваться/декодироваться (8/10 или 64/66) для передачи
FC-2 Кадрирование и сигнализация : определяет структуру передаваемой информации, занимается контролем целостности данных и управляет непосредственно передачей данных. На этом уровне происходит разбиение потока данных на кадры и сборка кадров. Определяет правила передачи данных между двумя портами, классы обслуживания.
FC-3 Общий для узла служб : заложен для нового функционала, который может быть реализован в протоколе, но на данный момент этот уровень не используется
FC-4 Отображения протоколов : описывает протоколы, которые для своей работы могут использоваться FC: проброс SCSI (SCSI-FCP) или TCP/IP (FC-LE)

Так же как и в сетевом протоколе, любое устройство в SAN сети имеет собственный уникальный 64-разряднй идентификатор - WWN, задаваемый производителем (аналогия с MAC-адресом сетевого устройства), так же каждое устройство получает 24-х битный адрес в сети, который дается при подключении устройства. Основой SAN сети является Фабрика - совокупность всех подключенных к сети устройств. Стоит отметить, что фабрика сама по себе является единой точкой отказа, по этому в SAN сетях нормальной практикой является построение нескольких параллельных фабрик (обычно двух), которые являются зеркальным отражением друг друга. Это позволяет строить отказоустойчивые решения. Хотя порой фабрики могут и отличаться (к примеру, дублируется подключение только критически важных систем) - всё зависит от возлагаемых на них задач.

Основой передачи данных в FC сетях является кадр. Кадр содержит в себе не только данные, но и заголовок, которые описывает служебную информацию из разряда - "откуда-куда", а так же разделите, указывающие на качало и конец фрейма.


Start of Frame - 4 байта - идентификатор начала фрейма.
Header - 24 байта - заголовок. Содержит такую информацию как адрес источника и приёмника, тип фрейма, номер последовательности и порядковый номер фрейма в ней и прочая служебно-контрольная информация.
Data - 0-2112 байт - непосредственно данные.
CRC - 4 байта - контрольная сумма.
End of Frame - 4 байта - идентификатор конца фрейма.

Последовательность представляет собой набор кадров, которые передаются из одной точки в другую. Для исправления возможных ошибок каждый кадр содержит уникальный счетчик последовательности. Исправление ошибок осуществляется протоколом более высокого уровня, обычно на уровне FC-4. Несколько последовательностей составляют обмен (exchange). Обмены представляют собой последовательности двусторонних направлений; т.е. в обмен входят последовательности данных, передающихся в разных направлениях, хотя каждая последовательность передается только в одном направлении. При каждом обмене только одна последовательность может быть активна в текущий момент времени. Но, так как одновременно могут быть активны несколько обменов, различные последовательности из этих обменов также могут быть активны одновременно. Каждый обмен выполняет одну функцию, например реализует команду SCSI Read.


Типы портов :
Порты узлов :
N_Port (Node port), порт устройства с поддержкой топологии FC-P2P («Точка-Точка») или FC-SW (с коммутатором).
NL_Port (Node Loop port), порт устройства с поддержкой топологии FC-AL (arbitrated loop - управляемая петля).

Порты коммутатора/маршрутизатора (только для топологии FC-SW) :
F_Port (Fabric port), порт «фабрики» (switched fabric - коммутируемая связная архитектура). Используется для подключения портов типа N_Port к коммутатору. Не поддерживает топологию петли.
FL_Port (Fabric Loop port), порт «фабрики» с поддержкой петли. Используется для подключения портов типа NL_Port к коммутатору.
E_Port (Expansion port), порт расширения. Используется для соединения коммутаторов. Может быть соединён только с портом типа E_Port.
EX_port порт для соединения FC-маршрутизатора и FC-коммутатора. Со стороны коммутатора он выглядит как обычный E_port, а со стороны маршрутизатора это EX_port.
TE_port (Trunking Expansion port (E_port)) внесен в Fibre Channel компанией CISCO, сейчас принят как стандарт. Это расширенный ISL или EISL. TE_port предоставляет, помимо стандартных возможностей E_port, маршрутизацию множественных VSANs (Virtual SANs). Это реализовано применением нестандартного кадра Fibre Channel (vsan-тегирование).

Общий случай :
U_Port (Universal port), порт, который ещё не определился в каком режиме он работает. Обычно после инициализации становится F_Port или E_Port.
L_Port (Loop port), любой порт устройства с поддержкой топологии «Петля» - NL_port или FL_port.
G_port (Generic port), порт с автоопределением. Автоматически может определяться как порт типа E_Port, N_Port, NL_Port.

SAN состоит из :

  • Узлы, ноды
    • Дисковые массивы (системы хранения данных)
    • Серверы
    • Ленточные библиотеки
  • Сетевая инфраструктура
    • Коммутаторы (и маршрутизаторы в сложных и распределённых системах)
    • Директоры - многопортовые модульные коммутаторы с высокой степенью доступности.
    • Выделенные коммутаторы (standalone switches) - коммутаторы с фиксированным количеством портов.
    • Стэкируемые коммутаторы (stackable switches) - коммутаторы, имеющие дополнительные высокопроизводительные порты для связи независимых шасси между собой.
    • Встраиваемые коммутаторы (embedded switches) - коммутаторы, встраиваемые в блейд-корзину, где есть разделение портов на функции (порты, предназначенные для подключения blade-серверов, не могут быть использованы для межкоммутаторных соединений).

Сердцем оборудование для SAN сетей является ASIC (application specific integrated circuit) - специализированная схема, разработанная компанией Brocade для возможности реализации большей части функционала оборудования на аппаратном уровне, что в итоге приводит к более высокой производительности и надёжности. Именно использование ASIC позволяет удерживать столь низкие задержки в SAN-сетях.

Он обеспечивает плавный переход между FC-0 и FC-1, занимаясь:

  • Encoder / Decoder - обеспечивает кодирование каждых 8 бит передаваемых данных в 10-битное представление. И декодирование обратно принимаемых данных.
  • SERDES (Serializer / Deserializer) - преобразует параллельный поток 10-битных порций данных в последовательный поток 10-битных порций данных.
  • Transceiver - преобразует электрические импульсы в световые сигналы.

ASIC обслуживает сами порты, при этом - ОС коммутатора работает на отдельных чипах, по этому при обновлении прошивки коммутатора у вас нет недоступности. На момент перезагрузки ОС - ASIC продолжает обслуживать текущие соединения, но блокирует установление новых. Подробнее об этом мы поговорим 6 части материала.

И раз уж на картинке выше у нас есть SFP:
SFP - это отдельные модули, необходимые для подключения кабеля к порту, но о них подробнее, о их типах и различиях я буду говорить в следующих материалах.

Я очень надеюсь что всё что я смог выжать из себя сегодня - удобоваримо и понятно для читателя. Ведь без основ двигаться дальше очень сложно, с точки зрения понимания процессов работы системы. Лично для меня - теория всегда была самой сложной частью. Не все вещи можно просто понять, как "трава зелёная", некоторые вещи нужно просто принять и запомнить как они работают.