-Поиск по дневнику

Поиск сообщений в rss_rss_hh_new

 -Подписка по e-mail

 

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 17.03.2011
Записей:
Комментариев:
Написано: 51

Habrahabr/New








Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://habrahabr.ru/rss/new/.
Данный дневник сформирован из открытого RSS-источника по адресу http://feeds.feedburner.com/xtmb/hh-new-full, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

[Перевод] Математический детектив: поиск положительных целых решений уравнения

Четверг, 10 Августа 2017 г. 08:51 + в цитатник
«Я экспериментировал с задачами кубического представления в стиле предыдущей работы Эндрю и Ричарда Гая. Численные результаты были потрясающими…» (комментарий на MathOverflow)
Вот так ушедший на покой математик Аллан Маклауд наткнулся на это уравнение несколько лет назад. И оно действительно очень интересно. Честно говоря, это одно из лучших диофантовых уравнений, которое я когда-либо видел, но видел я их не очень много.

Я нашёл его, когда оно начало распространяться как выцепляющая в сети нердов картинка-псевдомем, придуманная чьим-то безжалостным умом (Сридхар, это был ты?). Я не понял сразу, что это такое. Картинка выглядела так:


«95% людей не решат эту загадку. Сможете найти положительные целочисленные значения?»

Вы наверно уже видели похожие картинки-мемы. Это всегда чистейший мусор, кликбэйты: «95% выпускников МТИ не решат её!». «Она» — это какая-нибудь глупая или плохо сформулированная задачка, или же тривиальная разминка для мозга.

Но эта картинка совсем другая. Этот мем — умная или злобная шутка. Примерно у 99,999995% людей нет ни малейших шансов её решить, в том числе и у доброй части математиков из ведущих университетов, не занимающихся теорией чисел. Да, она решаема, но при этом по-настоящему сложна. (Кстати, её не придумал Сридхар, точнее, не он полностью. См. историю в этом комментарии).

Вы можете подумать, что если ничего другое не помогает, то можно просто заставить компьютер решать её. Очень просто написать компьютерную программу для поиска решений этого кажущегося простым уравнения. Разумеется, компьютер рано или поздно найдёт их, если они существуют. Большая ошибка. Здесь метод простого перебора компьютером будет бесполезен.

Не знаю, удастся ли уместить полное решение в статью, если не принять, что все уже знают всё необходимое об эллиптических кривых. Я могу привести здесь только краткий обзор. Основной справочный источник — это чудесная, относительно недавняя работа Бремнера и Маклауда под названием «An unusual cubic representation problem» («Необычная проблема кубического представления»), опубликованная в 2014 году в Annales Mathematicae et Informaticae.

Итак, приступим.



Мы ищем положительные целочисленные решения уравнения

$\frac{a}{b+c}+\frac{b}{a+c}+\frac{c}{a+b}=4 \tag 1$


(я заменил обозначения переменных теми, которые используются в работе).

Первое, что нужно сделать, исследуя любое уравнение — попробовать поместить его в нужный контекст. Надо задать вопрос: что это за уравнение? Так, нас просят найти целочисленные решения, то есть это задача теории чисел. В текущей формулировке в уравнении используются рациональные функции (многочлены, делящиеся на другие многочлены), но очевидно, что мы можем домножить на общее кратное знаменателей, чтобы подчистить уравнение и получить только многочлены, то есть привести его к виду диофантова уравнения. Требование «положительности» довольно необычно, и, как мы увидим, усложняет всё.

Итак, сколько же у нас тут переменных? Вопрос кажется глупым: очевидно, что три, а именно $a$, $b$ и $c$. Но не торопитесь. Опытный исследователь теории чисел мгновенно заметит, что уравнение однородное. Это значит, что если $(a,b,c)$ является одним из решений уравнения, то решением является и $(7a,7b,7c)$. Понимаете, почему? Умножив каждую переменную на какую-нибудь постоянную ($7$ — это просто пример), мы ничего не изменим, потому что константа в каждой из частей сокращается.

$\frac{ta}{tb+tc}=\frac{ta}{t(b+c)}=\frac{a}{b+c}$


Это значит, что уравнение только притворяется трёхмерным. На самом деле оно двухмерно. В геометрическом представлении у нас есть поверхность (одно уравнение с тремя переменными в общем случае задаёт двухмерную поверхность. В целом, $k$ уравнений с $n$ переменными задают $d$-мерное многообразие, где $d=n-k$). Но эта поверхность на самом деле ограничена линией, колеблющейся и проходящей через начало координат. Получившуюся поверхность можно понять, разобравшись в том, как она рассекает единичную плоскость. Это проективная кривая.

Проще всего объянить это сведение можно так: мы можем разделить решения, какими бы они ни были, на те, при которых $c=0$, и те, при которых $c\neq 0$. В первом случае у нас остаётся всего две переменные, $a$ и $b$, а во втором мы просто можем разделить на $c$ и получить решение при $c=1$. Поэтому мы можем просто искать рациональные решения в $a$ и $b$ для случая $c=1$, умножать их на общий делитель и получать целочисленное решение в $a$, $b$ и $c$. В сущности, целочисленные решения однородных уравнений соответствуют рациональным решениям неоднородной версии, которая на одну размерность меньше.

Продолжим: какова степень нашего уравнения? Степень уравнения — это максимальная степень, любого появляющаяся в уравнении одночлена, где «одночлен» — это произведение нескольких переменных, чья «степень» является количеством перемножаемых одночленов. Например, $a^2bc^4$ будет одночленом степени $7=2+1+4$.

Поведение диофантовых уравнений сильно зависит от их степени. В целом:

  • Со степенью $1$ всё просто.
  • Степень $2$ полностью проанализирована и может быть решена довольно элементарными способами.
  • Степень $3$ — это обширный океан глубокой теории и миллион нерешённых проблем.
  • Степень $4$ и выше… Очень, очень сложны.

Мы имеем степень $3$. Почему? Мы просто умножаем на делители:

$a(a+b)(a+c)+b(b+a)(b+c)+c(c+a)(c+b)=4(a+b)(a+c)(b+c)$


Даже без раскрывания скобок можно увидеть, что степень равна $3$: мы никогда не перемножаем более трёх переменных за раз. У нас получатся части типа $a^3$, $b^2c$ и $abc$, но никогда не будет чего-то больше трёх множителей. Если провести преобразования, то уравнение будет иметь вид

$a^3+b^3+c^3-3(a^2b+ab^2+a^2c+ac^2+b^2c+bc^2)-5abc=0$


Вы можете возразить, что умножение на делители невозможно, если какие-то из них оказываются равны $0$. Это верно — действительно, наше новое уравнение имеет несколько решений, не соответствующих исходному уравнению. Но на самом деле это хорошо. Версия с многочленами добавляет к оригиналу несколько «заплаток» и с ним становится проще работать. Нам просто нужно будет проверять, не исчезают ли исходные делители при каждом конкретном решении.

На самом деле уравнение с многочленами легко решить, например, $a=-1$, $b=1$, $c=0$. Это хорошо: у нас есть рациональное решение (рациональная точка). Это значит, что наше кубическое уравнение (степень = 3) на самом деле является эллиптической кривой.

Когда обнаруживаешь, что уравнение представляет собой эллиптическую кривую, то а) радуешься и б) отчаиваешься, потому что предстоит ещё много чего изучить. Это уравнение — прекрасный пример того, как мощную теорию эллиптических кривых можно применить к нахождению безумно сложно определяемых решений.



Первое, что обычно делают эллиптической кривой — приводят её в вейерштрассову форму. Это уравнение, которое выглядит как

$y^2 = x^3 + ax + b$


а иногда как

$y^2 = x^3 + ax^2+bx+c$


(это называется развёрнутой вейерштрассовой формой. Она необязательна, но иногда более удобна).

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

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

$x = \frac{-28(a+b+2c)}{6a+6b-c}$


$y = \frac{364(a-b)}{6a+6b-c}$


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

$y^2 = x^3+109x^2+224x \tag 2$


Это уравнение, хоть и выглядит совсем по-другому, на самом деле является достоверной моделью исходного. Графически оно выглядит так — типичная эллиптическая кривая с двумя вещественными частями:



«Рыбий хвост» справа растёт «в бесконечность и дальше». Овальная фигура слева является замкнутой и оказывается для нас довольно интересной.

Имея любое решение $(x,y)$ этого уравнения, мы можем восстановить необходимые значения $a$, $b$, $c$ с помощью уравнений

$a = \frac{56-x+y}{56-14x}$


$b = \frac{56-x-y}{56-14x}$


$c = \frac{-28-6x}{28-7x}$


(Помните, что триплет $(a:b:c)$ нужно воспринимать проективно – какие бы значения вы ни получили с помощью этих уравнений, их всегда можно умножить на любую константу).

Два показанных нами отображения, из $a$, $b$, $c$ в $x$, $y$ и наоборот, показывают, что эти два уравнения «одинаковы» с точки зрения теории чисел: рациональные решения одного дают рациональные решения другого. Технически это называется бирациональной эквивалентностью, а она является фундаментальным понятием алгебраической геометрии. Как мы уже заметили, могут существовать точки-исключения, которые не отображаются правильно. Это случаи, когда $a+b$, $a+c$ или $b+c$ оказываются равны $0$. Это привычная расплата в случае бирациональной эквивалентности, и она не должна вызывать никаких волнений.



Давайте рассмотрим пример.

На эллиптической кривой (2) есть хорошая рациональная точка:

$x=-100$, $y=260$. Возможно, её не так просто найти, но очень просто проверить: просто вставьте эти значения и вы увидите, что две половины одинаковы (я выбирал эту точку не случайным образом, но пока это неважно). Можно просто проверить, какие значения $a$, $b$, $c$ она нам даёт. Мы получаем $a = 2/7$, $b=-1/14$, $c=11/14$, и поскольку мы можем умножить на общий делитель, то результаты преобразуются в $a = 4$, $b=-1$, $c=11$.

И в самом деле,

$\frac{4}{-1+11}+\frac{-1}{4+11}+\frac{11}{4-1}=4$


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

Теперь, получив рациональную точку на эллиптической кривой, например, $P=(-100,260)$ на нашей кривой (2), можно начать генерировать другие с помощью техники хорд и касательных, рассмотренной в предыдущей статье на Quora.



Для начала прибавим нашу точку $P$ к ней самой, найдя касательную к кривой в точке $P$ и определив, где она снова встречается с кривой. Результат будет немного пугающим:

$P+P=2P=(8836/25, -950716/125)$


и снова эта новая точка соответствует значениям $a$, $b$, $c$, являющимся решением исходного уравнения

$(a,b,c)=(9499, -8784, 5165)$


Это решение определённо непросто найти вручную, но оно всё ещё под силу компьютеру. Однако оно по-прежнему неположительно.

Не пугаясь неудач, мы продолжаем вычислять $3P=2P+P$, что можно определить соединением прямой линией $P$ и $2P$ и нахождением третьей точки пересечения с кривой. И снова мы вычисляем $a$, $b$, $c$, и снова результат неположителен. То же самое будет и с $4P$, и с $5P$, и так далее… пока мы не наткнёмся на $9P$.

9P=(-66202368404229585264842409883878874707453676645038225/13514400292716288512070907945002943352692578000406921,
58800835157308083307376751727347181330085672850296730351871748713307988700611210/1571068668597978434556364707291896268838086945430031322196754390420280407346469)


Его определённо непросто найти, но с помощью нашей машинерии нам достаточно повторить девять раз простую геометрическую процедуру. Соответствующие значения $a$, $b$, $c$ потрясающи:

a=154476802108746166441951315019919837485664325669565431700026634898253202035277999,
b=36875131794129999827197811565225474825492979968971970996283137471637224634055579,
c=4373612677928697257861252602371390152816537558161613618621437993378423467772036


Это 80-разрядные числа! Вы никак не смогли бы найти 80-разрядные числа на компьютере с помощью простого перебора. Выглядит невероятным, но вставив эти огромные числа в простое выражение $a/(b+c)+b/(a+c)+c/(a+b)$, мы действительно получим ровно $4$.

Фактически, они являются наименьшими решениями задачи. Если мы продолжим прибавлять к самой себе точку $P$, то при этом просто будут расти делители. Непросто это доказать, потому что всегда есть вероятность сокращения, но теория высот для эллиптической кривой позволяет нам показать, что эти астрономические числа на самом деле являются простейшим решением уравнения.





Вернёмся к теории. Эллиптическая кривая над рациональными значениями имеет ранг, который является количеством точек, необходимых, чтобы использовать для метод хорд и касательных и быть уверенным, что мы рано или поздно найдём все рациональные точки на кривой. Наша эллиптическая кривая (2) имеет ранг 1. Это значит, что у неё есть бесконечное количество рациональных точек, но все они получаются из единственной, которая является ничем иным, как нашей точкой $P=(-100, 260)$. Алгоритмы вычисления ранга и нахождения такого генератора далеки от тривиальных, но SageMath (теперь имеющий название CoCalc) выполняет их меньше чем за секунду всего в нескольких строках кода. Мой код можно посмотреть здесь. Он воспроизводит всё решение с нуля, но, конечно же, использует встроенные методы Sage для работы с эллиптическими кривыми.

В нашем случае точка $P$ лежит на овальной части кривой, как и точки $mP$ для любого положительного целого $m$. Они «кружатся» по овалу и постепенно довольно равномерно по нему распределяются. Это очень удачно, потому что только небольшая часть этого овала даёт положительные решения в отношении $a$, $b$, $c$: это выделенная жирным часть графика ниже, взятого из работы Бремнера и Маклауда.



Точки $P$, $2P$, и так далее, не лежат на выделенной части, а $9P$ — лежит, именно так мы и получили наши 80-разрядные положительные решения.

Бремнер и Маклауд изучили, что происходит, если мы заменяем $4$ чем-то другим. Если вы думаете, что решения будут большими, то подождите, пока не увидите, какими окажутся решения при результате $178$. Вместо 80 разрядов нам понадобится 398 605 460 разрядов. Да, это только количество разрядов решения. Если заменить результат на $896$, то решение будет содержать триллионы разрядов. Триллионы. Для этого невинно выглядящего уравнения:

$a/(b+c)+b/(a+c)+c/(a+b)=896$




Поразительный пример того, как диофантовы уравнения с небольшими коэффициентами могут иметь огромные решения. Это внушает не просто трепет, а ощущение бездонности. Отрицательное решение десятой проблемы Гильберта означает, что рост решений при увеличении коэффициентов — это невычислимая функция, потому что если бы она была вычисляемой, то у нас был бы простой алгоритм решения диофантовых уравнений, а его не существует (ни простого, ни сложного). Соответствие $4 \to$ 80-разрядные числа, $178 \to$ числа из сотен миллионов разрядов и $896 \to$ триллионы разрядов даёт нам небольшое представление о первых, небольших шагах этой чудовищной невычислимой функции. Немного измените числа в уравнении, и решения запросто превзойдут всё, что может вместиться в нашу жалкую, крошечную Вселенную.

Вот такое удивительно хитрое небольшое уравнение.

Благодарю пользователя MrShoor, приславшего мне ссылку на эту интересную статью.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335248/


Метки:  

Несколько слов о тестировании сложных аппаратных комплексов

Четверг, 10 Августа 2017 г. 08:45 + в цитатник
Привет. Сегодня я хочу поговорить с вами о тестировании железа — с болезненными примерами и фотографиями из обыденной практики. Эту суровую реальность с пайкой, дебагом и сожженными чипами обычно все беспощадно лакируют, рассказывая только об успехах — ответственные за пиар и маркетинг люди обычно как огня боятся любых упоминаний об ошибках и сбоях. Но инженеры понимают, что сложные комплексы сразу безупречными не рождаются, поэтому мы не боимся рассказать вам про тестирование как есть. Ну и поделиться опытом, что делать, а чего избегать.



Предварительная подготовка


— Everyone please observe the fasten seat belt and no smoking signs have been turned on. Sit back and enjoy your ride.

Итак, по порядку.
Тестирование осуществляется на всех стадиях жизни аппаратуры. Тестирование бывает первоначальное (bringup), компонентное, функциональное, нагрузочное, производственное, и даже тестирование на заказчиках.

Еще на стадии разработки аппаратуры инженер думает о том, как он будет оживлять свое детище. Платы обсыпаются контрольными точками, отладочными коннекторами, перемычками, посадочными местами для запасных компонентов и прочим подобным. Совокупность возможностей для тестирования, заложенных в аппаратуру, называется DFT (Design for Testability). Плата, выпущенная в DFT фазе, может содержать в два раза больше компонентов, чем плата, вышедшая в тираж. Естественно, следуя принципу «работает – не трогай», потом ее никто не переделывает, и конечный потребитель недоуменно рассматривает пустующие посадочные места на материнской плате из магазина, придумывая различные конспирологические теории по поводу их предназначения.



Итак, нам произвели наш борд – что делать дальше? Ну конечно же – воткнуть в розетку и выпустить из него весь белый дым.


— Everybody falls the first time.

Фотка из интернета, у нас жжёных плат не нашлось, но каюсь – иногда так и делается. На моей памяти есть давняя история, когда любопытный системный архитектор сидел и подбирал наугад в какие разъёмы нужно воткнуть фазу, нейтраль и землю (ну вот не было у него времени заглянуть в схему), а рядом сидел разработчик и ловил бледного.

Но обычно всё происходит по-другому. Первая фаза тестирования – bringup (в народе «оживляш»).

Оживление Рождение


— Wake up, Neo...

Для bringup обычно изготавливается 3—5 образцов (в расчете на то, что как минимум два будут уничтожены в бреду дебага). Если в составе устройства есть дорогие чипы — на один из образцов они не устанавливаются. Фаб может предложить вам сэкономить на золоте — НИ В КОЕМ СЛУЧАЕ НЕ СОГЛАШАЙТЕСЬ (ну просто паять придется много и часто).



Плата без чипа — это первый кандидат на убой. На ней проверяются последовательность включения питания, сбросы, номиналы напряжений и прочее подобное. Потом такая плата является донором органов и/или полигоном для проверки всяческих гипотез. Также перед тем как что-то включать, нужно обязательно:
  • прозвонить землю-питание, там частенько есть КЗ;
  • визуально осмотреть плату – там запросто бывает перепутана полярность конденсаторов, чипы стоят вверх ногами, присутствует стружка, с лёгкостью можно найти пассивные компоненты, которые оторвали;
  • отдельно изучить – а не поставили ли вам на плату компоненты, которые вы просили не ставить (лайфхак: не делайте черную маску на первых сэмплах – на ней не видно установлены или нет чип-резисторы).

Наигрались с первой жертвой – идем пускать дым из боевой платы. При этом необходимо запастись пилотом с кнопкой отрубания питания и тепловизором. Пилот надо поставить под ногу, на случай если по рукам будет бить 220 В (ну или просто руки будут заняты), а в тепловизор можно увидеть КЗ.



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



И еще припаять немножко проводов:


Термоклей — наше все, лучший друг разработчика, почти как скотч в обычной жизни.
Сразу после Дремеля:


И молотка, которым приходится забивать бонки в плату, — не всегда выходит аккуратно.



Иногда приходится делать пациенту рентген или томографию. Выглядит это так:

Отсканировать плёнку, оказывается, не очень просто. Сняли телефоном на просвет напротив окна.

Конкретно на этом снимке не видно ничего — не вглядывайтесь. Но вообще на рентгене можно увидеть непропай, трещины и прочее подобное.

Отдельно стоит сказать про bringup материнских плат, потому что делается он по-другому. DFT сэмплов матерей обычно заказывается много – порядка 20 штук. Стоит это дорого, поэтому тут своя стратегия.

Берутся разработчики и отправляются на фабрику. Собирается порядка 5 плат и конвейер останавливается. Далее у разработчиков есть порядка 30 минут, чтобы плату включить (для x86-систем критерий успеха — загрузить BIOS). Если всем повезло — собираются остальные образцы. Если нет — производство отменяется, а разработчики едут домой думать. Деньги затраченные на PCB — потеряны, зато компоненты ждут на складе следующей попытки.

Хорошо — мы запустили нашу плату, и даже запустили другие, которые должны работать вместе с ней. Что дальше? Собираем стенд.
И тут вы, наверное, ожидаете увидеть такое?


Это все показуха для замминистров. Настоящий стенд должен быть собран из палок и желудей, и выглядит так:

— I didn't say it would be easy, Neo. I just said it would be the truth.
(стакан для противовеса, фломастер — чтоб радиатор внатяг сидел — оно там проводом примотано)

Или так:


В лабораторию набивается вот такая орда:


И все начинают наперегонки зашивать свои прошивки, программки, и тыкать везде осциллографом.
Иногда процессе то и дело раздается вежливая просьба «Дорогой коллега, пожалуйста, уберите паяльник от моей руки — уж очень горячо» или «Будьте так добры — больше не включайте источник питания, когда я привинчиваю плату к шасси».

Питерский офис очень на нас влияет. Как гласит наш веб-сайт:


В нашем конкретном случае основная цель проверки совместной работы нескольких устройств — узнать, работает ли PCI Express, соответствует ли он стандарту. Просто без всего остального в принципе можно жить. Обычно функционал, закладываемый в железку, избыточен. Тонны GPIO выводов, I2C/SPI шин, термодатчиков, ледов и прочего, как правило, остаются невостребованными, так как их отладку откладывают на последний момент, который никогда не наступает.

Естественно, у нас нет на каждый случай жизни измерительной аппаратуры за несколько миллионов рублей — это для слабаков. Нам на помощь спешит тестовое ПО от производителей компонентов. Практически все современные чипы с высокоскоростными интерфейсами имеют внутри цифровой осциллограф. К нему полагается специализированное ПО, позволяющее считать его показания. Запускаем и смотрим глазковые диаграммы. Видим такое:


Иногда видим опасный прищур:


А иногда ловим кальмаров:


Кальмары — самые опасные. Это нелинейные искажения, и встроенные эквалайзеры с таким бороться особо не умеют. Кальмары означают, что где-то в канале связи есть что-то очень плохое — слишком длинное переходное отверстие, существенный перепад импеданса, попадание какой-то неравномерности в 1/4 или 1/2 длины волны каких-то гармоник в полезной полосе и прочее подобное.
Кто-то, возможно, заметит, что кальмар немного похож на то, что делает с принятым сигналом DFE в эквалайзере приемника PCIe. Но в данном случае это таки кальмар, а не результат работы DFE (просто результат работы DFE используемое нами ПО отображать не умеет).

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

Ну и да — если вы планируете снимать глаза по интерфейсу I2C — забудьте, это будет очень очень очень медленно. Только in-band. Проблема в том, что для съема in-band у Вашего устройства должен быть рабочий PCIe линк с компьютером, где работает тестовое ПО, что весьма проблематично когда Ваша железка не устанавливается в стандартный PCIe слот. И что самое забавное — у Вас уже должен быть хоть как-то работающий линк на том канале, который вы отлаживаете, причем именно в том режиме (gen2/3) в котором вам нужно (ибо в разных режимах разные глаза и по разному работают эквалайзеры). Нет ножек, нет мультиков линка, нет глаз — вот как хотите, так и выкручивайтесь.

Про то, как выкручиваться с PCIe — я ранее написал отдельную статью.

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

В процессе проведения проверок иногда выясняется, что где-то что-то идет не так. И тогда начинается увлекательный процесс локализации ошибки, чтобы ее можно было исправить в следующей ревизии. И хорошо если это «не так» стабильно повторяется – тогда выяснить, что именно является причиной ошибки, как правило, не составляет труда. Но иногда все гораздо хуже. Например, на некоторых экземплярах плат при длительном прогоне тестов возникают одиночные некорректируемые ошибки на шине (которых быть не должно совсем). И вот здесь зачастую уже приходится применять метод «пристального взгляда» — то есть просто сидеть, гипотетически глядя на схему предполагать, что именно может быть причиной, пробовать эту гипотетическую причину устранить в схеме, и тестами уже проверить – угадали мы или нет.

Мы с подобным сталкивались несколько лет назад, когда тесты NVIDIA (да, многие производители предоставляют специфические наборы тестов, которые позволяют проверить вещи, недоступные программным путем при использовании стандартных утилит) давали редкие одиночные ошибки при длительных (сутки и более) прогонах на некоторых экземплярах плат. Тогда все дело оказалось в неудачной трассировке референсного клока (100 MHz) — хотя прежде чем мы к этому пришли, проверено было много всего, начиная от качества питания и заканчивая глазковыми диаграммами по всем линиям.

И кстати, это хорошо. Самый большой кошмар разработчика — когда все работает сразу. Это значит только одно — где-то закопана мина, которая сработает после отгрузки 100500 единиц оборудования заказчику. Дело в том, что в процессе поиска причины какой-то глобальной проблемы осуществляется проверка нескольких гипотез и как правило выявляется множество мелких неисправностей, никак с возникшей проблемой не связанных. Нет большой проблемы — не найдёте маленьких. Их за вас найдут ваши заказчики.

Проверка по списку


— All I do is what he tells me to do.

После завершения компонентных тестов начинается функциональное тестирование – проверка работоспособности комплекса в целом и корректной работы всех заложенных функций. Обычно этим занимается QA. Простор для творчества здесь, конечно, весьма обширный, но в целом основной упор делается на корректную работу системы при проигрывании стандартных сценариев использования. Здесь обнаруженные ошибки могут уже иметь как аппаратную, так и программную природу, поэтому в первую очередь важно выяснить, что именно вызвало ошибку. Зачастую первые предположения могут быть обманчивыми, то есть явно аппаратная на первый взгляд проблема может быть вызвана некорректной работой встроенного ПО. Значительную часть в функциональном тестировании занимает проверка того, как система отрабатывает разнообразные ошибки, которые могут возникать в процессе работы. Современные отладочные средства позволяют осуществлять искусственную инжекцию ошибок в стандартные интерфейсы процессоров, потому что на уровне железа многие из них создать специально достаточно проблематично (ну не отрывать же на лету чипы памяти или замыкать линии шины PCI Express).

А… я же не сказал, что функциональное тестирование не означает собранную готовую к бою систему. Тут тоже бывает не все гладко. В какой-то момент оказалось что у нас нет в запасе OcuLink кабелей нужной длины, и у сервера появились кишки.


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

А два арбуза в каждой руке унести сможешь?


— You're faster than this. Don't think you are, know you are…

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

Кроме того, здесь помогают отладочные средства от производителя аппаратной платформы (например, Hardware Tests Executive от IBM). Таким образом можно загнать процессор в совсем предельные режимы, принципиально недостижимые при работе реальных приложений. Основные проблемы, выявляемые при нагрузочном тестировании – перегрев, нестабильность питания или перегрузка по максимальному току, ошибки при активной работе с интерфейсами ввода-вывода.

Также на помощь приходят бенчмарки. Потому что когда реальные значение бенчмарков сильно отличаются от прогнозируемых — значит что-то пошло не так. Хороший повод пойти потыкать плату палочкой.

На стадии тестирования мы используем в основном микробенчмарки:
Для процессоров это обычно однопоточные нагрузки, типа spec2006 (сейчас уже speccpu2017), parsec, но вообще их огромное количество от сборки ядра linux и компрессии (lzma, gzip), до перемножения матриц и вычисления быстрого преобразования Фурье (fftw).
Для памяти много лет ничего не меняется: STREAM, RAMspeed SMP, lmbench.
Для дисков: fio, iozone.

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

P.S.: После того как мы на функциональных тестах первой ревизии сервера все проверили и обрадовались, у нас в лаборатории внезапно обвалилось три сервера. Мы начали проверять питание и на линии 1.2В (питание шины PCIe процессоров) увидели вот такое:


Акцентирую ваше внимание — одна клетка 500mV. Номинал 1.2В. Резистором ошиблись в цепи компенсации одного из VRM. Вот с таким вот питанием были успешно пройдены все нагрузочные тесты, бенчмарки, прожарки и прочее подобное, и дизайн радостно поехал на вторую ревизию.
Так что, когда на Вашем уютном домашнем компьютере именитого бренда внезапно появляется экран смерти — не стоит думать, что это непременно «глючит винда».
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335306/


Метки:  

Model-View-Intent и индикатор загрузки/обновления

Четверг, 10 Августа 2017 г. 05:11 + в цитатник

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


  • при переходе на экран показывать индикатор загрузки (ProgressBar) в то время, как данные грузятся с сервера;
  • в случае ошибки загрузки показать сообщение об ошибке и кнопку "Повторить загрузку";
  • в случае успешной загрузки дать пользователю возможность обновлять данные (SwipeRefreshLayout);
  • если при обновлении данных произошла ошибка, показать соответствующее сообщение (Snackbar).

При разработке приложений я использую архитектуру MVI (Model-View-Intent) в реализации Mosby, подробнее о которой можно почитать на Хабре или найти оригинальную статью о MVI на сайте разработчика mosby. В этой статье я собираюсь рассказать о создании базовых классов, которые позволили бы отделить описанную выше логику загрузки/обновления от остальных действий с данными.


Первое, с чего мы начнем создание базовых классов, это создание ViewState, который играет ключевую роль в MVI. ViewState содержит данные о текущем состоянии View (которым может быть активити, фрагмент или ViewGroup). С учетом того, каким может быть состояние экрана, относительно загрузки и обновления, ViewState выглядит следующим образом:


// Здесь и далее LR используется для сокращения Load-Refresh.
data class LRViewState>(
        val loading: Boolean,
        val loadingError: Throwable?,
        val canRefresh: Boolean,
        val refreshing: Boolean,
        val refreshingError: Throwable?,
        val model: M
)

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


В LRViewState модель реализует интерфейс InitialModelHolder, о котором я сейчас расскажу.
Не все данные, которые будут отображены на экране или будут еще как-то использоваться в пределах экрана, должны быть загружены с сервера. К примеру, имеется модель, которая состоит из списка людей, который загружается с сервера, и нескольких переменных, которые определяют порядок сортировки или фильтрацию людей в списке. Пользователь может менять параметры сортировки и поиска еще до того, как список будет загружен с сервера. В этом случае список — это исходная (initial) часть модели, которая грузится долго и на время загрузки которой необходимо показывать ProgressBar. Именно для того, чтобы выделить, какая часть модели является исходной используется интерфейс InitialModelHolder.


interface InitialModelHolder {
    fun changeInitialModel(i: I): InitialModelHolder
}

Здесь параметр I показывает какой будет исходная часть модели, а метод changeInitialModel(i: I), который должен реализовать класс-модель, позволяет создать новый объект модели, в котором ее исходная (initial) часть заменена на ту, что передана в метод в качестве параметра i.


То, зачем нужно менять какую-то часть модели на другую, становится понятно, если вспомнить одно из главных преимуществ MVI — State Reducer (подробнее тут). State Reducer позволяет применять к уже имеющемуся объекту ViewState частичные изменения (Partial Changes) и тем самым создавать новый экземпляр ViewState. В дальнейшем метод changeInitialModel(i: I) будет использоваться в State Reducer для того, чтобы создать новый экземпляр ViewState с загруженными данными.


Теперь настало время поговорить о частичных изменениях (Partial Change). Частичное изменение содержит в себе информацию о том, что именно нужно изменить в ViewState. Все частичные изменения реализуют интерфейс PartialChange. Этот интерфейс не является частью Mosby и создан для того, чтобы все частичные изменения (те, которые касаются загрузки/обновления и те, что не касаются) имели общий "корень".


Частичные изменения удобно объединять в sealed классы. Далее Вы можете видеть частичные изменения, которые можно применить к LRViewState.


sealed class LRPartialChange : PartialChange {
    object LoadingStarted : LRPartialChange() // загрузка началась
    data class LoadingError(val t: Throwable) : LRPartialChange() // загрузка завершилась с ошибкой
    object RefreshStarted : LRPartialChange() // обновление началось
    data class RefreshError(val t: Throwable) : LRPartialChange() // обновление завершилось с ошибкой
    // загрузка или обновления завершились успешно
    data class InitialModelLoaded(val i: I) : LRPartialChange()
}

Следующим шагом является создание базового интерфейса для View.


interface LRView> : MvpView {
    fun load(): Observable
    fun retry(): Observable
    fun refresh(): Observable

    fun render(vs: LRViewState)
}

Здесь параметр K является ключем, который поможет презентеру определить какие именно данные нужно загрузить. В качестве ключа может выступать, например, ID сущности. Параметр M определяет тип модели (тип поля model в LRViewState). Первые три метода являются интентами (в понятиях MVI) и служат для передачи событий от View к Presenter. Реализация метода render будет отображать ViewState.


Теперь, когда у нас есть LRViewState и интерфейс LRView, можно создавать LRPresenter. Рассмотрим его по частям.


abstract class LRPresenter, V : LRView>
        : MviBasePresenter>() {
    protected abstract fun initialModelSingle(key: K): Single

    open protected val reloadIntent: Observable = Observable.never()

    protected val loadIntent: Observable = intent { it.load() }
    protected val retryIntent: Observable = intent { it.retry() }
    protected val refreshIntent: Observable = intent { it.refresh() }

    ...
    ...
}

Параметры LRPresenter это:


  • K ключ, по которому загружается исходная часть модели;
  • I тип исходной части модели;
  • M тип модели;
  • V тип View, с которой работает данный Presenter.

Реализация метода initialModelSingle должна возвращать io.reactivex.Single для загрузки исходной части модели по переданному ключу. Поле reloadIntent может быть переопределено классами-наследниками и используется для повторной загрузки исходной части модели (например, после определенных действий пользователя). Последующие три поля создают интенты для приема событий от View.


Далее в LRPresenter идет метод для создания io.reactivex.Observable, который будет передавать частичные изменения, связанные с загрузкой или обновлением. В дальнейшем будет показано, как классы-наследники могут использовать этот метод.


protected fun loadRefreshPartialChanges(): Observable = Observable.merge(
            Observable
                    .merge(
                            Observable.combineLatest(
                                    loadIntent,
                                    reloadIntent.startWith(Any()),
                                    BiFunction { k, _ -> k }
                            ),
                            retryIntent
                    )
                    .switchMap {
                        initialModelSingle(it)
                                .toObservable()
                                .map { LRPartialChange.InitialModelLoaded(it) }
                                .onErrorReturn { LRPartialChange.LoadingError(it) }
                                .startWith(LRPartialChange.LoadingStarted)
                    },
            refreshIntent
                    .switchMap {
                        initialModelSingle(it)
                                .toObservable()
                                .map { LRPartialChange.InitialModelLoaded(it) }
                                .onErrorReturn { LRPartialChange.RefreshError(it) }
                                .startWith(LRPartialChange.RefreshStarted)
                    }
    )

И последняя часть LRPresenter это State Reducer, который применяет к ViewState частичные изменения, связанные с загрузкой или обновлением (эти частичные изменения были переданы из Observable, созданном в методе loadRefreshPartialChanges).


@CallSuper
open protected fun stateReducer(viewState: LRViewState, change: PartialChange): LRViewState {
    if (change !is LRPartialChange) throw Exception()
    return when (change) {
        LRPartialChange.LoadingStarted -> viewState.copy(
                loading = true,
                loadingError = null,
                canRefresh = false
        )
        is LRPartialChange.LoadingError -> viewState.copy(
                loading = false,
                loadingError = change.t
        )
        LRPartialChange.RefreshStarted -> viewState.copy(
                refreshing = true,
                refreshingError = null
        )
        is LRPartialChange.RefreshError -> viewState.copy(
                refreshing = false,
                refreshingError = change.t
        )
        is LRPartialChange.InitialModelLoaded<*> -> {
            @Suppress("UNCHECKED_CAST")
            viewState.copy(
                    loading = false,
                    loadingError = null,
                    model = viewState.model.changeInitialModel(change.i as I) as M,
                    canRefresh = true,
                    refreshing = false
            )
        }
    }
}

Теперь осталось создать базовый фрагмент или активити, который будет реализовывать LRView. В своих приложениях я придерживаюсь подхода SingleActivityApplication, поэтому создадим LRFragment.


Для отображения индикаторов загрузки и обновления, а также для получения событий о необходимости повторения загрузки и обновления был создан интерфейс LoadRefreshPanel, которому LRFragment будет делегировать отображение ViewState и который будет фасадом событий. Таким образом фрагменты-наследники не обязаны будут иметь SwipeRefreshLayout и кнопку "Повторить загрузку".


interface LoadRefreshPanel {
    fun retryClicks(): Observable
    fun refreshes(): Observable

    fun render(vs: LRViewState<*>)
}

В демо-приложении был создан класс LRPanelImpl, который представляет собой SwipeRefreshLayout с вложенным в него ViewAnimator. ViewAnimator позволяет отображать либо ProgressBar, либо панель ошибки, либо модель.


С учетом LoadRefreshPanel LRFragment будет выглядеть следующим образом:


abstract class LRFragment, V : LRView, P : MviBasePresenter>> : MviFragment(), LRView {

    protected abstract val key: K

    protected abstract fun viewForSnackbar(): View
    protected abstract fun loadRefreshPanel(): LoadRefreshPanel

    override fun load(): Observable = Observable.just(key)

    override fun retry(): Observable = loadRefreshPanel().retryClicks().map { key }

    override fun refresh(): Observable = loadRefreshPanel().refreshes().map { key }

    @CallSuper
    override fun render(vs: LRViewState) {
        loadRefreshPanel().render(vs)
        if (vs.refreshingError != null) {
            Snackbar.make(viewForSnackbar(), R.string.refreshing_error_text, Snackbar.LENGTH_SHORT)
                .show()
        }
    }
}

Как видно из приведенного кода, загрузка начинается сразу же после присоединения презентера, а все остальное делегируется LoadRefreshPanel.


Теперь создание экрана, на котором необходимо реализовать логику загрузки/обновления становится несложной задачей. Для примера рассмотрим экран с подробностями о человеке (гонщике, в нашем случае).


Класс сущности — тривиальный.


data class Driver(
        val id: Long,
        val name: String,
        val team: String,
        val birthYear: Int
)

Класс модели для экрана с подробностями состоит из одной сущности:


data class DriverDetailsModel(
        val driver: Driver
) : InitialModelHolder {
    override fun changeInitialModel(i: Driver) = copy(driver = i)
}

Класс презентера для экрана с подробностями:


class DriverDetailsPresenter : LRPresenter() {

    override fun initialModelSingle(key: Long): Single = Single
            .just(DriversSource.DRIVERS)
            .map { it.single { it.id == key } }
            .delay(1, TimeUnit.SECONDS)
            .flatMap {
                if (System.currentTimeMillis() % 2 == 0L) Single.just(it)
                else Single.error(Exception())
            }

    override fun bindIntents() {
        val initialViewState = LRViewState(false, null, false, false, null,
                DriverDetailsModel(Driver(-1, "", "", -1))
        )
        val observable = loadRefreshPartialChanges()
                .scan(initialViewState, this::stateReducer)
                .observeOn(AndroidSchedulers.mainThread())
        subscribeViewState(observable, DriverDetailsView::render)
    }
}

Метод initialModelSingle создает Single для загрузки сущности по переданному id (примерно каждый 2-й раз выдается ошибка, чтобы показать как выглядит UI ошибки). В методе bindIntents используется метод loadRefreshPartialChanges из LRPresenter для создания Observable, передающего частичные изменения.


Перейдем к созданию фрагмента с подробностями.


class DriverDetailsFragment
    : LRFragment(),
      DriverDetailsView {

    override val key by lazy { arguments.getLong(driverIdKey) }

    override fun loadRefreshPanel() = object : LoadRefreshPanel {
        override fun retryClicks(): Observable = RxView.clicks(retry_Button)
        override fun refreshes(): Observable = Observable.never()
        override fun render(vs: LRViewState<*>) {
            retry_panel.visibility = if (vs.loadingError != null) View.VISIBLE else View.GONE
            if (vs.loading) {
                name_TextView.text = "...."
                team_TextView.text = "...."
                birthYear_TextView.text = "...."
            }
        }
    }

    override fun render(vs: LRViewState) {
        super.render(vs)
        if (!vs.loading && vs.loadingError == null) {
            name_TextView.text = vs.model.driver.name
            team_TextView.text = vs.model.driver.team
            birthYear_TextView.text = vs.model.driver.birthYear.toString()
        }
    }

    ...

    ...
}

В данном примере ключ хранится в аргументах фрагмента. Отображение модели происходит в методе render(vs: LRViewState) фрагмента. Также создается реализация интерфейса LoadRefreshPanel, которая отвечает за отображение загрузки. В приведенном примере на время загрузки не используется ProgressBar, а вместо этого поля с данными отображают точки, что символизирует загрузку; retry_panel появляется в случае ошибки, а обновление не предусмотрено (Observable.never()).


Демо-приложение, которое использует описанные классы, можно найти на GitHib.
Спасибо за внимание!

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335112/


Разрушители легенд — Gentoo Linux

Среда, 09 Августа 2017 г. 19:39 + в цитатник
Дочка Убунту прибежала к Дебиану и, весело смеясь, поцеловала его в лоб: "С днём рождения, папа!". Затем она окинула радостным взглядом сидящих за столом гостей и спросила своим звонким голосом:
— Папа, а где Gentoo, разве он ещё не пришёл?
— Нет, он ещё только собирается.

Среди прочих Linux дистрибутивов Gentoo выделяется тем, что его окружает множество мифов, светлой и темной окраски. Я его использую более 10 лет в качестве домашней и офисной рабочей станции и хочу с вами разоблачить несколько мифов и создать парочку новых.




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


Миф №1 — прирост производительности


Gentoo Linux дает прирост производительности за счет того, что все программы компилируются под конкретное пользовательское железо. На этапе зарождения и становления дистрибутива этот тезис звучал с лютой настойчивостью.


Это на самом деле не совсем миф, но вы скорее всего не заметите прироста производительности, если не ставите целью доказать это статистически, вооружившись Phoronix Test Suite или чем-то подобным. Возможно исключение для FireFox, собранного с профилированием, USE="pgo".


На чем основан этот миф? Действительно узкий круг вычислительных программ можно ускорить при компиляции под определенную платформу, задавая компилятору включение инструкций SIMD, AESNI, или AVX. Бинарные дистрибутивы из-за чрезмерной заботы о совместимости со старой архитектурой базой зачастую приносят подобные оптимизации в жертву. Вернее будет сказать, что так было раньше, а сейчас это не играет большой роли.


Определенно, не за это адепты ценят Gentoo.


Миф №2 — обновления съедают много времени


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


(5:515)$ sudo qlop -t libreoffice firefox qtwebengine
libreoffice: 15028 seconds average for 20 merges
firefox: 3127 seconds average for 32 merges
qtwebengine: 8884 seconds average for 5 merges

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


# Part 1
layman -S
emerge --sync
eix-update

# Part 2
emerge -avuND --with-bdeps=y --complete-graph=y --backtrack=30 --keep-going --verbose-conflicts --exclude "gentoo-sources firefox libreoffice chromium glibc perl python gcc" world
smart-live-rebuild -- -av --with-bdeps=y --complete-graph=y
emerge -av --exclude "gentoo-sources firefox libreoffice chromium glibc perl python gcc" @preserved-rebuild
eclean distfiles

Миф №3 — в Gentoo самые свежие версии программ


Конечно, если сравнивать с Debian Linux, то в целом это так, однако и тут бывают исключения. Тот же Debian раньше стал использовать Grub 2 в стабильной ветке и Perl какое-то время был более новой версии, нежели в Gentoo. Если же сравнивать стабильные ветки менее консервативных дистрибутивов с таковыми в Gentoo, то результат может быть каким угодно. Все зависит от кучи обстоятельств, насколько данный пакет обеспечен мейнтейнером и волонтерами. Например QEMU обновляется почти одновременно со стабильной веткой Github, а MATE — застрял в Gentoo на версии 1.12.2 из-за того, что у него мало разработчиков.


(5:499)$ eix -ce qemu;eix -ce mate
[I] app-emulation/qemu (2.9.0-r2@19.05.2017): QEMU + Kernel-based Virtual Machine userland tools
[N] mate-base/mate (1.12-r1): Meta ebuild for MATE, a traditional desktop environment

+1 — необычайная гибкость настроек


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


  • Systemd или OpenRC, решайте сами.
  • Pulseaudio ставить или нет, думайте.
  • Включить поддержку dri3 в mesa и Xorg или оставить dri2?
  • Собрать незамутненную 64-битную ОС без 32-х битных библиотек совместимости или не стоит упарываться нарываться?
  • Какие кодеки включить в ffmpeg, mpv, vlc?
  • Как насчет альтернативного пакетного менеджера, если штатные emerge и portage вас не устраивают?

+2 — скользящие релизы


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


Все важные изменения изменения доносят до пользователей заблаговременно через механизм рассылки новостей. Прочитать последние актуальные новости дистрибутива можно командой eselect news read.


(5:501)$ sudo eselect news read
No news is good news.

+3 — хорошая документация


Это действительно так. Установку ОС значительно облегчает подробнейшее руководство, но есть также крайне полезные вики и форум.


Туда же входят упомянутые рассылки новостей и сообщения elog в специальных файлах /var/log/portage/elog.


± emerge и portage


Основная система управления пакетами portage и штатное средство управления пакетами emerge являются очень мощным и функциональным в руках опытного и внимательного к докам пользователя. Именно благодаря системе portage возможны тонкие и гибкие настройки операционной систему и пользовательского ПО (см. выше в +1). Даже беглое описание возможностей emerge/portage заслуживает отдельного поста, поэтому ограничусь общим описанием.


  • Установка и обновление программ позволяет указать нужные и ненужные опции, которые соответственно будут включены в них или исключены из них во время сборки. Это задается USE флагами, которые транслируются в --enable-<опция> и --disable-<опция> инструкции .configure скрипта установки из исходников.
  • Удаление программ тупо их удаляет, не заботясь о зависимостях. Так что будьте осторожны с тем, что вы собираетесь удалить. Если удалить python или gcc, придется затем скачивать бинарные пакеты, так как emerge впадет в ступор и будет не в состоянии собрать программу из исходников.
  • Поиск в базе данных пакетов, список файлов в пакете, определение пакета по заданному файлу, зависимости данного пакета, история операций emerge и прочие полезности.
  • Настройка производится правкой текстовых файлов, что не удивительно. С другой стороны таких файлов несколько и надо знать, что за что отвечает.
  • Обсчет зависимостей, парсинг древа портов происходит довольно медленно и это зачастую нервирует. Стандартная проверка обновлений может занять 2 минуты прежде чем выдать результат на экран.
  • Иногда случаются блокировки, конфликты между пакетами в момент обновления. В большинстве случаев такие ситуации устраняются за пару минут, если пользователь сносно знает матчасть. Однако в крайне редких случаях можно встрять надолго и распутывать зависимости по часу, а то и более.

Из-за чего могут возникать такие ситуации? По самым разным причинам, изменения в лицензировании продукта, необходимость замаскировать, или наоборот размаскировать пакет, изредка ляпы разработчиков. Тут наблюдается обратная зависимость от частоты обновлений, поэтому рекомендуется регулярно и по возможности часто обновлять систему, чтобы накопленная энтропия в древе портов не порождала цепной реакции.


-1 — начальная установка занимает много времени


Полная ерунда, вот установка с помощью однострочника.


wget goo.gl/5Y2Gj -O install.sh && sh install.sh

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


  1. Качественная документация, о чем говорилось выше.
  2. SystemRescueCd — дистрибутив, созданный с целью восстановления работоспособности системы после аварии, основан на Gentoo. SystemRescueCd очень полезен в качестве установщика, позже на заключительном этапе вам пригодится образ ядра загрузочного LiveCD образа, если возникнут трудности с настройкой и сборкой ядра.
  3. Средство автоматизированной сборки ядра gentoolkit позволяет безболезненно пройти самый запутанный и неформализуемый процесс конфигурации и сборки ядра. Другие утилиты из набора portage-utils, eix, eselect и другие позволят хорошо ориентироваться в порядке и зависимостях установленных пакетов и избежать состояний блокировки.

Маленькие хитрости


Если по каким-то причинам компиляция пакета прервалась (выключился свет, завис компьютер и т. д.), но технически может быть возобновлена, можно продолжить процесс с этого самого места. Это особенно ценно для LibreOffice, Chromium или qt-webengine, которые собираются не один час.


  1. ebuild /usr/portage/cate-gory/prog/prog-x.y.z.ebuild compile
  2. ebuild /usr/portage/cate-gory/prog/prog-x.y.z.ebuild install
  3. ebuild /usr/portage/cate-gory/prog/prog-x.y.z.ebuild qmerge

Смонтируйте /var/tmp/portage и /usr/portage на SSD, а если у вас немерено оперативной памяти, то можно и на tmpfs, это даст заметный прирост скорости работы emerge.


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


quickpkg --include-config y <установленная программа>

Использованные материалы и полезные ссылки


Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335022/


Метки:  

[Из песочницы] Как повысить шансы при поиске работы и получить максимум приглашений на перспективные собеседования при минимуме времени

Среда, 09 Августа 2017 г. 19:32 + в цитатник
В данной публикации привожу рекомендации, выработанные на основе опыта поиска как работы, так и сотрудников. Все рекомендации проверены опытом и сформулированы в виде конкретных практических действий с короткими пояснениями. Рекомендации приводятся на примере одного из самых популярных сайтов по поиску работы.

Резюме в открытом доступе


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

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

Если не хотите, чтобы вас могли легко идентифицировать (например, на текущем месте работы), то в настройках отметьте компанию, у которой не должны быть доступа к вашему резюме. Проверьте разные названия и юридические лица компании, так как существует вероятность, что у вашего работодателя несколько аккаунтов. Тем не менее, это не дает 100% гарантии, что ваш текущий работодатель не увидит, что вы ищете работу, поэтому вы можете использовать дополнительно другие варианты: не используйте вашу фамилию, вместо названия компания обозначьте сферу деятельности, например, компания входит в ТОП-10 телеком, или производство детской одежды, или интернет-агентство.

Отклики на вакансии


Настройте автопоиски по разным вариантам названия вакансий. Откликайтесь несколько раз на одну вакансию, если не получаете ответа (приглашения или отказа). Только между откликами делайте паузу в несколько дней или неделю. А на самые интересные для вас вакансии откликайтесь с таким же названием, как указано в описании вакансии, возможно, для этого вам придется создать отдельное резюме, но это можно сделать за пару минут, и, возможно, это же резюме пригодится для других интересных вакансий.

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

В этом же кратком списке можно открыть сопроводительное письмо, поэтому сопроводительные письма нужны. Чтобы оно было нешаблонным, можно взять несколько основных требований из вакансии и указать, что соответствуете. Например: опыт работы менеджером по продажам в телеком, свободное знание английского языка, опыт продаж крупным брендовым клиентам. Или в сопроводительном письме можно обобщить свой опыт и указать достижения: 5 лет работы менеджером по продажам, 5 раз становился лучшим продавцом месяца за последний год и пр. Не буду советовать делать резюме специально под отдельную вакансию, как это часто рекомендуют в большом количестве статей на данную тему, но призываю для особенно интересных вам вакансий вносить изменения в шаблон сопроводительного письма, которые покажут, что вы внимательно ознакомились с требованиями вакансии и соответствуете им. Этим вы облегчите задачу HR-специалисту и повысите ваши шансы на собеседование.

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

Дополнительные каналы


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

Указание желаемого дохода


Можно указать в тех случаях, если ваши зарплатные ожидания находятся в среднерыночном диапазоне (с учетом вашего опыта и навыков), а вы не хотите получать приглашения на собеседования в компании, где заплата будет ниже. Но учтите, что в данном случае этот параметр может также являться отсекающим фактором.

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

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

Прохождение тестов и выполнение тестовых заданий


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

Если тест является для вас сложным или нужно много времени, то оцените, насколько интересна вам вакансия, стоит ли тратить время.

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

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

Буду рада, если поделитесь полученным опытом.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335286/


Метки:  

12 полезных сайтов для творческих коллективов

Среда, 09 Августа 2017 г. 17:42 + в цитатник

Метки:  

[Перевод] Как Discord масштабировал Elixir на 5 млн одновременных пользователей

Среда, 09 Августа 2017 г. 17:34 + в цитатник
С самого начала Discord активно использовал Elixir. Виртуальная машина Erlang стала идеальным кандидатом для создания высокопараллельной системы реального времени, которую мы собирались создать. Первоначальный прототип Discord был разработан на Elixir; сейчас он лежит в основе нашей инфраструктуры. Задача и предназначение Elixir простые: доступ ко всей мощи Erlang VM через гораздо более современный и дружественный язык и набор инструментов.

Прошло два года. Сейчас у нас пять миллионов одновременных пользователей, а через систему проходят миллионы событий в секунду. Хотя мы абсолютно не сожалеем о выборе архитектуры, пришлось проделать массу исследований и экспериментов, чтобы добиться такого результата. Elixir — это новая экосистема, а экосистеме Erlang не хватает информации о её использовании в продакшне (хотя Erlang in Anger — это нечто). По итогу всего пути, пытаясь приспособить Elixir для работы в Discord, мы извлекли некоторые уроки и создали ряд библиотек.

Веерное развёртывание сообщений


Хотя у Discord много функций, в основном всё сводится к pub/sub. Пользователи подключаются к WebSocket и раскручивают сессию (GenServer), которая затем устанавливает соединение с удалёнными узлами Erlang, где работают guild-процессы (тоже GenServer'ы). Если что-то публикуется в guild (внутреннее именование “Discord Server”), оно разворачивается веером на каждую подключенную сессию.



Когда пользователь выходит в онлайн, он подключается к guild'у, а тот публикует статус присутствия во все остальные подключенные сессии. Есть и много другой логики, но вот упрощённый пример:

def handle_call({:publish, message}, _from, %{sessions: sessions}=state) do
  Enum.each(sessions, &send(&1.pid, message))
  {:reply, :ok, state}
end

Это был нормальный подход, когда мы изначально создали Discord для групп из 25 или менее пользователей. Однако нам повезло столкнуться с «хорошими проблемами» роста, когда люди начали использовать Discord в больших группах. В итоге мы пришли к тому, что на многих серверах Discord вроде /r/Overwatch присутствует до 30 000 пользователей одновременно. В пиковые часы мы наблюдали, что эти процессы не справляются с очередями сообщений. В определённый момент пришлось вручную вмешаться и отключить функции генерации сообщений, чтобы помочь справиться с нагрузкой. Нужно было разобраться с проблемой до того, как она приобретёт масштабный характер.

Мы начали с бенчмарков для самых нагруженных путей в рамках процессов guild и вскоре выявили очевидную причину неприятностей. Обмен сообщениями между процессами Erlang оказался не таким эффективным, как нам казалось, а единица работы Erlang для шедулинга процессов тоже обходилась весьма дорого. Мы обнаружили, что время одного вызова send/2 может варьироваться от 30 мкс до 70 мкс из-за дешедулинга процесса вызова Erlang. Это означало, что в пиковые часы публикация одного события с большого guild'а может занять от 900 мс до 2,1 с! Процессы Erlang полностью однопоточные, и единственным вариантом параллелизации представлялись шарды. Такое мероприятие потребовало бы немалых сил, и мы знали, что найдётся лучший вариант.

Нужно было как-то распределить работу по рассылке сообщений. Поскольку процессы spawn в Erlang обходятся дёшево, нашей первой идеей было просто спаунить новый процесс для обработки каждого публикуемого сообщения. Однако все публикации могли происходить в разное время, а клиенты Discord зависят от линеаризуемости событий. К тому же, такое решение нельзя хорошо масштабировать, потому что у сервиса guild становилось всё больше работы.

Вдохновлённые постом в блоге о повышении производительности в передаче сообщений между нодами, мы создали Manifold. Manifold распределяет работу по рассылке сообщений между удалёнными нодами с идентификаторами PID (идентификатор процессов в Erlang). Это гарантирует, что процессы рассылки будут вызывать send/2 максимум столько раз, сколько вовлечено удалённых нодов. Manifold делает это, сначала группируя PID'ы по их удалённым нодам, а затем отправляя их в «разделитель» Manifold.Partitioner на каждой из этих нод. Затем разделитель последовательно хеширует PID'ы, используя :erlang.phash2/2, группирует их по количеству ядер и отправляет на дочерние воркеры. В конце концов, воркеры рассылают сообщения в реальные процессы. Это гарантирует, что разделитель не перегружен и продолжает обеспечивать линеаризуемость, как send/2. Такое решение стало эффективной заменой send/2:

Manifold.send([self(), self()], :hello)

Замечательным побочным эффектом Manifold стало то, что нам удалось не только распределить нагрузку CPU веерных сообщений, но и снизить сетевой трафик между нодами:


Снижение сетевого трафика на одну ноду Guild

Manifold лежит на GitHub, так что пробуйте.

Общие данные быстрого доступа


Discord — распределённая система, которая применяет консистентное хеширование. Использование этого метода потребовало создания кольцевой структуры данных, которую можно использовать для поиска ноды конкретного объекта. Мы хотели, чтобы система работала быстро, поэтому выбрали замечательную библиотеку Криса Муса, подключив её через порт Erlang C (процесс, отвечающий за интерфейс с кодом C). Она отлично работала, но по мере масштабирования Discord мы начали замечать проблемы во время всплесков с переподключением пользователей. Процесс Erlang, отвечающий за управление кольцом, начинал настолько загружаться работой, что не мог справиться с запросами к кольцу, и вся система не справлялась с нагрузкой. Решение на первый взгляд выглядело очевидным: запустить множество процессов с данными кольца для лучшего использования всех ядер машины, чтобы обработать все запросы. Но это слишком важная задача. Есть ли лучший вариант?



Давайте посмотрим на составляющие.

  • Пользователь может быть в любом количестве guild'ов, но средний показатель 5.
  • Ответственная за сессии виртуальная машина Erlang VM может поддерживать до 500 000 сессий.
  • При подключении сессии ей нужно найти удалённую ноду для каждого guild'а, который ей интересен.
  • Время коммуникации с другим процессом Erlang, используя request/reply, составляет около 12 мкс.

Если сессионный сервер сбоил и перезагружался, уходило около 30 секунд просто на поиски в кольце. Это даже не считая дешедулинга со стороны Erlang одного процесса, вовлечённого работу других процессов кольца. Можем ли мы полностью устранить эти издержки?

При работе с Elixir, если нужно ускорить доступ к данным, первым делом принято использовать ETS. Это быстрый, изменяемый словарь на C; обратной стороной медали является то, что данные копируются туда и считываются оттуда. Мы не могли просто перевести наше кольцо на ETS, потому что использовали порт C для управления кольцом, так что мы переписали код на чистом Elixir. Как только это было закончено, у нас появился процесс, который владел кольцом и непрерывно копировал его в ETS, так что другие процессы могли считывать данные напрямую из ETS. Это заметно подняло производительность, но операции чтения ETS занимали около 7 мкс и мы по-прежнему тратили 17,5 секунд на операции поиска значений в кольце. Структура данных кольца на самом деле довольно большая, и копирование её в ETS и считывание оттуда занимало основную часть времени. Мы были разочарованы; на любом другом языке программирования можно было просто сделать общее значение для безопасного чтения. Должен быть какой-то способ сделать это на Erlang!

После некоторого исследования мы нашли модуль mochiglobal, который использует функцию виртуальной машины: если Erlang встречает функцию, которая постоянно возвращает одни и те же данные, он помещает эти данные в доступную только для чтения кучу с общим доступом, к которой имеют доступ процессы. Копирование не требуется. mochiglobal использует это, создавая модуль Erlang с одной функцией и компилируя его. Поскольку данные никуда не копируются, расходы на поиск уменьшились до 0,3 мкс, что снизило общее время до 750 мс! Впрочем, полной халявы не бывает; само создание модуля со структурой данных такого размера в рантайме может занимать до секунды. Хорошая новость в том, что мы редко меняем кольцо, так что готовы заплатить такую цену.

Мы решили портировать mochiglobal на Elixir и добавить некоторую функциональность, чтобы избежать атомизации. Наша версия называется FastGlobal.

Ограниченный параллелизм


После решения важной проблемы с производительностью поиска ноды, мы заметили, что процессы, ответственные за обработку поиска guild_pid в нодах guild стали давать задний ход. Медленный поиск нод раньше защищал их. Новая проблема заключалась в том, что около 5 000 000 сессионных процессов пытались давить на десять из этих процессов (по одному на каждой ноде guild). Здесь ускорение обработки не решало проблему; фундаментальной причиной было то, что обращения сессионных процессов к этому реестру guild'ов вываливались в таймаут и оставляли запрос в очереди к реестру. После некоторого времени запрос повторялся, но постоянно накапливаемые запросы переходили в неустранимое состояние. Получая сообщения из других сервисов, сессии блокировали бы эти запросы до тех пор, пока они не уйдут в таймаут, что приводило к раздуванию очереди сообщений и, в итоге, к OOM всей Erlang VM, результатом чего становятся каскадные перебои в обслуживании.

Нужно было сделать сессионные процессы умнее; в идеале, они не должны даже пытаться делать эти вызовы к реестру guild'ов, если неудачный исход неизбежен. Мы не хотели использовать автоматический выключатель, чтобы не возникла ситуация, когда всплеск таймаутов приводит к временному состоянию, когда не делается вообще никаких попыток. Мы знали, как реализовать такое на других языках, но как сделать это на Elixir?

В большинстве других языков мы могли бы использовать атомарный счётчик для отслеживания исходящих запросов и раннего оповещения, если их количество слишком велико, эффективно реализуя семафор. Erlang VM построена на координации между процессами, но мы не хотели слишком загружать процесс, ответственный за эту координацию. После некоторых исследований мы наткнулись на :ets.update_counter/4, который выполняет атомарные операции с обусловленных приращением на числе, которое находится в ключе ETS. Поскольку нужна была хорошая параллелизация, можно было запустить ETS в режиме write_concurrency, но по-прежнему считывать значение, поскольку :ets.update_counter/4 возвращает результат. Это дало нам фундаментальную основу для создания библиотеки Semaphore. Её исключительно легко использовать, и она очень хорошо работает с высокой пропускной способностью:

semaphore_name = :my_sempahore
semaphore_max = 10
case Semaphore.call(semaphore_name, semaphore_max, fn -> :ok end) do
  :ok ->
    IO.puts "success"
  {:error, :max} ->
    IO.puts "too many callers"
end

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


Работа сервисов присутствия


Использование CPU сессионными сервисами за тот же период

Можете найти нашу библиотеку Semaphore на GitHub.

Заключение


Выбор и работа с Erlang и Elixir оказались отличным опытом. Если бы нас заставили вернуться и начать заново, мы определённо выбрали бы тот же путь. Надеемся, что рассказ о нашем опыте и инструментах будет полезен другим разработчикам Elixir и Erlang, а мы надеемся продолжить рассказывать о своей работе, решении проблем и получении опыта по ходу этой работы.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335220/


Комиксы Даниэля Стори (часть 2)

Среда, 09 Августа 2017 г. 17:07 + в цитатник
Привет, Хабр! Помните подборку юмористических IT-комиксов от Даниэля Стори (Daniel Stori). Первая часть собрала много положительных откликов. Сегодня мы вновь хотим порадовать всех очередной порцией веселья. Желаем приятного просмотра.



Уровни программиста



О языке Brainfuck, протоколе Telnet и утилите nmap.

Эскалация проблемы



Ссылки на nixCraft и OMG! Ubuntu!

Большие данные




Big data на Википедии

Современное зло









Вы готовы к переходу на микросервисы?







Потребовалось время. Интересная статья на Хабре.

Протоколы



TCP и UDP

Вольная трактовка



HTTP / 2 Server Push на Википедии.

Ресторан Agile



Методология Agile и Каскадная (Waterfall) модель

Обычное утро


Дэдлайны, которые уже мертвы


О ТАРДИС

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



Это Дюк
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335232/


Метки:  

Как workflow разработки влияет на декомпозицию задач

Среда, 09 Августа 2017 г. 17:05 + в цитатник


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


Давайте подумаем и обозначим проблемы, которые могут возникнуть в процессе разделения задач, и способы их решения. В этом посте будут рассмотрены основные принципы декомпозиции задач при работе в команде. Меня зовут Илья Агеев, я – глава QA в Badoo. Сегодня расскажу, как workflow влияет на декомпозицию, насколько отличаются тестирование и выкладка задач, которые появляются в результате декомпозиции, и каких правил стоит придерживаться, чтобы процесс разработки проходил гладко для всех участников.


Почему это важно?


Необходимо помнить о том, что процесс разработки – это не только непосредственно сеанс написания кода. Когда мы говорим о разработке, я призываю смотреть на весь процесс целиком, начиная от постановки задачи и заканчивая стабильной работой фичи у наших пользователей. Если не брать в расчёт все этапы, которые предшествуют кодированию и следуют за ним, то очень легко можно попасть в ситуацию, когда все что-то делают, выполняют свои KPI, получают бонусы, а результат получается плачевный. Бизнес загибается, конкуренты «душат», но при этом все – молодцы.


Почему так происходит? Всё просто: человеческая психология заставляет людей смотреть на ситуации с точки зрения собственного комфорта. Разработчику не всегда хочется думать о том, что будет с кодом после его написания. Решил задачу – и хорошо. Его крайне редко это интересует (именно поэтому мы, айтишники, и работаем в этой отрасли – наша мотивация в основном держится на интересности задач), ведь в отношениях с людьми столько неопределённости. Гораздо более комфортно многие разработчики чувствуют себя, сидя за компьютером и сосредоточившись на решении своей собственной интересной задачи – блокчейнах с нейросетями – им совсем не хочется отвлекаться и думать о каких-то продакт-менеджерах, дедлайнах, пользователях, которые потом будут использовать их гениальное произведение (а то ещё и критиковать начнут!).


Это не плохо и не хорошо – мы ценим разработчиков именно за вдумчивое и грамотное решение технических задач. Но узкий взгляд на проблемы часто останавливает развитие. И речь о развитии не только конкретных людей, но и компании в целом. Ведь рост компании и совершенствование корпоративной культуры возможны только с ростом каждого сотрудника. Поэтому нам важно иногда вылезать из «кокона» и заставлять себя смотреть на проблемы шире, чтобы этот рост стимулировать.


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


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


Хороший пример – написание юнит-тестов. Зачем мне тратить своё драгоценное время на написание тестов, если у нас есть тестировщики, которые потом и так всё протестируют? А затем, что юнит-тесты необходимы не только для облегчения процесса кодинга – они нужны также и на последующих этапах. И нужны как воздух: с ними процесс интеграции и проверки регрессии ускоряется в десятки, сотни раз, на них базируется пирамида автоматизации. И это даже если не брать в расчёт ускорение вашей собственной работы: ведь «потрогав» код в каком-то месте, вам самому нужно убедиться в том, что вы ненароком что-нибудь не сломали. И один из самых быстрых способов это сделать – прогнать юнит-тесты.


Workflow


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


Стоит ли говорить, что если изначально договориться о процессе, не принимая во внимание весь жизненный цикл фичи, то можно получить замедление и «грабли» в будущем? Особенно если учесть рост проекта и компании. О преждевременной оптимизации не забываем, но если есть процесс, который хорошо работает на разных масштабах, то почему бы его не использовать изначально?


Говоря о workflow разработки, многие, кто использует Git, сразу вспоминают (всуе) о некоем «стандартном git-flow», считая его идеальным, правильным, и часто внедряют его у себя. Даже на конференциях, где я выступал, рассказывая про workflow в Badoo, меня несколько раз спрашивали: «Зачем вы изобрели своё, почему не используете стандартный git-flow?» Давайте разбираться.



Во-первых, обычно, говоря про этот флоу, имеют в виду вот эту картинку. Я взял её из статьи Vincent Driessen “A successful Git branching model”, в которой описывается схема, довольно успешно работавшая на нескольких его проектах (было это в далёком 2010 году).


Сегодня некоторые крупные игроки на рынке хостинга кода вообще предлагают свой флоу, критикуя «стандартный git-flow» и описывая его недостатки; дают свои схемы, рекомендации, приёмы.


Если же поискать на git-scm.com (хорошо бы вообще погуглить), то с удивлением можно обнаружить, что никакого рекомендованного (и уж тем более «стандартного») workflow не существует. Всё потому, что Git – это, по сути, фреймворк для систем хранения версий кода, и то, как вы организуете это самое хранение и совместную работу, зависит только от вас самих. Всегда нужно помнить о том, что, если какой-то флоу «взлетел» на каких-то проектах, это вовсе не означает, что вам он тоже полностью подойдёт.


Во-вторых, даже у нас в компании у разных команд разный флоу. Флоу разработки серверного кода на PHP, демонов на С/ С++ и Go, флоу мобильных команд – они разные. И пришли мы к этому не сразу: пробовали разные варианты, прежде чем остановиться на чём-то конкретном. К слову, отличается в этих командах не только workflow, но ещё и методологии тестирования, постановки задач, релизы и сам принцип доставки: то, что поставляется на ваши личные серверы и на компьютеры (смартфоны) конечных пользователей, не может разрабатываться одинаково по определению.


В-третьих, даже принятый workflow является скорее рекомендацией, чем непререкаемым правилом. Задачи у бизнеса бывают разные, и хорошо, если вам удалось выбрать процесс, покрывающий 95% случаев. Если же ваша текущая задача не вписывается в выбранный флоу, имеет смысл посмотреть на ситуацию с прагматической точки зрения: если правила мешают вам сделать эффективно, к чёрту такие правила! Но обязательно посоветуйтесь с вашим менеджером перед принятием окончательного решения – иначе может начаться бардак. Вы можете банально не учесть какие-то важные моменты, которые известны вашему руководителю. А, возможно, всё пойдёт как по маслу – и вы сумеете изменить существующие правила так, что это приведёт к прогрессу и станет залогом роста для всех.


Если всё так сложно, да ещё и флоу – это не догма, а всего лишь рекомендация, то почему бы не использовать одну ветку для всего: Master для Git или Trunk для SVN? Зачем усложнять?


Тем, кто смотрит на проблему однобоко, этот подход с одной веткой может показаться очень удобным. Зачем мучиться с какими-то ветками, париться со стабилизацией кода в них, если можно написать код, закоммитить (запушить) в общее хранилище – и радоваться жизни? И правда, если в команде работает не очень много человек, это может быть удобно, поскольку избавляет от необходимости слияния веток и организации веток для релиза. Однако данный подход имеет один очень существенный недостаток: код в общем хранилище может быть нестабильным. Вася, работающий над задачей №1, может легко сломать код других задач в общем хранилище, залив свои изменения; и пока он их не исправит/ не откатит, код выкладывать нельзя, даже если все остальные задачи готовы и работают.


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


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


Feature branches


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


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


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


Ещё опаснее конфликты, связанные с логикой кода, когда SCM сливает код без проблем (ведь по строкам в файлах конфликтов нет), но из-за изоляции разработки какие-то общие методы и функции в коде изменили своё поведение или вообще удалены из кода. В компилируемых языках проблема, как может показаться, стоит менее остро – компилятор валидирует код. Но ситуации, когда сигнатуры методов не поменялись, а логика изменилась, никто не отменял. Такие проблемы сложно обнаруживать, и они ещё более отдаляют счастливый релиз и заставляют перетестировать код много раз после каждого слияния. А когда разработчиков много, кода много, файлов много и конфликтов много, всё превращается в сущий ад, ибо пока мы исправляли код и перепроверяли его, основная версия кода уже ушла далеко вперёд, и надо всё повторять заново. Вы всё ещё не верите в юнит-тесты? Хе-хе-хе!


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


Отсюда – второе правило хорошей декомпозиции: фичебранчи должны содержать как можно меньше изменений, чтобы как можно быстрее попадать в общий код.


Параллельная работа


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


Тут многое зависит от вашего цикла релизов, потому что моментом завершения задачи мы считаем момент попадания её на продакшн. Ведь только этот момент гарантирует нам, что код стабилен и работает. Если не пришлось откатывать изменения с продакшна, конечно.


Если цикл релизов быстрый (несколько раз в день вы выкладываетесь на свои серверы), то вполне можно сделать фичи зависимыми друг от друга по стадиям готовности. В примере с Петей и Васей выше создаём не две задачи, а три. Соответственно, первая звучит как «меняем общий метод так, чтобы он работал в двух вариантах» (или заводим новый метод для Пети), а две другие задачи – это задачи Васи и Пети, которые могут начать работу после завершения первой задачи, не пересекаясь и не мешая друг другу.


Если же цикл релизов не позволяет вам выкладываться часто, то пример, описанный выше, будет непомерно дорогим удовольствием, ведь тогда Васе и Пете придётся ждать дни и недели (а в некоторых циклах разработки и года), пока они смогут начать работать над своими задачами.


В этом случае можно использовать промежуточную ветку, общую для нескольких разработчиков, но ещё недостаточно стабильную, чтобы быть выложенной на продакшн (Master или Trunk). В нашем флоу для мобильных приложений такая ветка называется Dev, на схеме Vincent Driessen она называется develop.


Важно иметь в виду, что любое изменение в коде, даже слияние веток, вливание общих веток в стабильный Master и т. д., обязательно должно быть протестировано (помните про конфликты по коду и логике, да?). Поэтому если вы пришли к выводу, что вам необходима общая ветка кода, то нужно быть готовым к ещё одному этапу тестирования – после момента слияния необходимо тестировать, как фича интегрируется с другим кодом, даже если она уже протестирована в отдельной ветке.


Тут вы можете заметить, что можно ведь тестировать только один раз – после слияния. Зачем тестировать до него, в отдельной ветке? Верно, можно. Но, если задача в ветке не работает или ломает логику, этот неработоспособный код попадёт в общее хранилище и мало того, что помешает коллегам работать над своими задачами, ломая какие-то участки продукта, так ещё и может подложить бомбу, если на неправильных изменениях кто-то решит базировать новую логику. А когда таких задач десятки, очень тяжело искать источник проблемы и чинить баги.


Также важно понимать, что, даже если мы используем промежуточную разработческую ветку кода, которая может быть не самой стабильной, задачи или их кусочки в ней должны быть более-менее завершёнными. Ведь нам необходимо в какой-то момент зарелизиться. А если в этой ветке код фич будет ломать друг друга, то выложиться мы не сможем – наш продукт работать не будет. Соответственно, протестировав интеграцию фич, нужно как можно скорее исправить баги. Иначе мы получим ситуацию, похожую на ту, когда используется одна ветка для всех.


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


Feature flags


Но как же быть в ситуации, когда новое изменение бизнес-логики – большое? Только на программирование такой задачи может уйти несколько дней (недель, месяцев). Не будем же мы сливать в общее хранилище недоделанные куски фич?


А вот и будем! В этом нет ничего страшного. Подход, который может быть применён в этой ситуации, – feature flags. Он основан на внедрении в код «выключателей» (или «флагов»), которые включают/ выключают поведение определённой фичи. К слову, подход не зависит от вашей модели ветвления и может использоваться в любой из возможных.


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


Последней задачей в процессе разработки новой большой фичи в этом случае будет задача «включить фичефлаг» (или «добавить пункт меню» в примере с новой страницей).


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


Заключение


Итак, при декомпозиции задач важно помнить три простых правила:


  1. Задачи должны быть в виде логически завершённых кусочков кода.
  2. Эти кусочки кода должны быть маленькими и должны максимально быстро попадать в общий код.
  3. Эти кусочки должны разрабатываться параллельно и выкладываться независимо друг от друга.

Куда уж проще? Кстати, независимая выкладка, на мой взгляд, — самый важный критерий. Из него так или иначе проистекают остальные пункты.


Желаю удачи в разработке новых фич!

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335254/


Метки:  

«Есть плюсы как для админов, так и для разработчиков»: Олег Анастасьев про облако Одноклассников

Среда, 09 Августа 2017 г. 17:03 + в цитатник


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

Поэтому переход Одноклассников от подхода «каждый сервер занимается своей задачей» к облачному подходу «единый пул ресурсов распределяется по необходимости» вызвал у нас вопросы. Мигрировать такой большой проект с 11-летней историей на новую систему непросто — что именно побудило пойти на эти трудозатраты? Чем использование облака в ОК отличается от использования публичных сервисов? Почему проекту не подходят стандартные решения вроде Mesos и Kubernetes, а вместо этого было сделано собственное one-cloud?

На эти и другие вопросы нам ответил ведущий разработчик Одноклассников Олег Анастасьев, уже знакомый читателям Хабра.


— Мы помним, что у вас есть «Правило большого З»: любое техническое действие должно отвечать на вопрос «Зачем?». Так вот, зачем вам понадобилось облако?

— Одна из причин в следующем. Оперирование напрямую с железками — это по большей части прерогатива системных администраторов, или system reliability engineers, называй их как хочешь. Мы хотим двигать разработчиков ближе к продакшену. А чтобы это сделать, надо дать им способ общаться с продакшеном таким способом, чтобы избавить людей от ненужной бюрократии, при этом не дав ничего повалить. И это один из способов решения задачи.

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

— Обычно про облака и плотную загрузку серверов говорят в таком контексте: «если у стартапа сегодня тысяча пользователей, а завтра миллион, с облаком можно быстро отмасштабироваться и использовать необходимое количество ресурсов, не переплачивая за неиспользуемое».

Но Одноклассники-то уже не стартап, у вас аудитория не может внезапно удвоиться, её рост медленнее и предсказуемее. Почему тогда без облака не обеспечить плотную загрузку серверов, выделяя их на каждую задачу ровно столько, сколько требуется?


— Здесь есть несколько соображений. Во-первых, да, аудитория более-менее стабильная, но это относится только к количеству пользователей: нагрузка растёт значительно быстрее. Сейчас в связи с тем, что очень быстро увеличивается потребление видео (в частности, лайв-трансляций), с точки зрения нагрузки мы растём в два раза за год — это при том, что у нас и так достаточно большая нагрузка.

Во-вторых, хотя Одноклассники в целом существуют давно, в них запускается довольно много различных новых продуктов: те же трансляции появились относительно недавно, много новых продуктов для администраторов групп, частных объявлений, музыки; наконец, мессенджер ТамТам. Про такие продукты заранее сложно оценить, насколько успешными они окажутся, как быстро их понадобится масштабировать. И если каждый сервер занимается своей задачей, неочевидно, сколько серверов требуется выделять. Это та же стартап-проблематика.

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

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

— Естественно, магии не существует, и на какие-то трейд-оффы приходится идти. И если раньше ты имел целый выделенный сервер под свои задачи, а теперь на этом сервере свальный грех, то есть риск, что полностью изолировать друг от друга задачи не получится. Но, насколько могу сейчас судить, общая отказоустойчивость системы в нашем случае стала только выше. Точно это смогут показать реальные, не симулированные, масштабные аварии, пока что с облаком их ещё не было.

— Почему потребность в облачном подходе ощутили именно сейчас? Что-то изменилось вообще в индустрии, или конкретно в Одноклассниках?

— Я думаю, что тут сошлись три фактора. В мире стали возникать новые более-менее опенсорсные системы управления инфраструктурой, и из подобных широко известных компонентов мы в нашей новой системе используем Docker. При планировании расширения инфраструктуры мы поняли, что место в существующих дата-центрах скоро закончится, и нам надо либо строить новый, либо уплотняться в существующих. И у нас освободились ресурсы, чтобы эту задачу наконец решить.

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

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

Понятно, что экономически невозможно просто поставить рядом с нашим дата-центром ещё один такой же большой с облаком, и переводить всё туда, надо использовать уже работающую технику. Поэтому, вводить всё больше и больше инфраструктуры в облако — сложная задача, выполняющаяся постепенно, её нельзя «просто взять и сделать».



А с другой стороны, тут требуется и поддержка со стороны разработчиков, они должны что-то менять в коде, делать контейнеры своих приложений (учтём, что всего у нас более чем 150 различных микросервисов)… В общем, это большой процесс. Первая версия облака у нас была написана и запущена далеко не один месяц назад, но миграция систем в облако всё ещё идёт.

— А насколько легко добиться этой «поддержки со стороны разработчиков» — не приходится ли сталкиваться с «нам тут фичи пилить надо, не хочется отвлекаться на инфраструктурные вопросы, лучше мы в облако попозже перейдём»?

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

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

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

— Многие крупные компании по всему миру делают свои облака. А почему они не готовы просто пользоваться условным Amazon AWS — потому что своё получается дешевле, потому что переживают о безопасности, или потому что хотят большой уровень контроля и доступа?

— Есть и те, кто идут в Amazon — так делают Netflix, пионеры облачных вычислений. Но они там поверх AWS запускают свою собственную систему автоматического управления инфраструктурой, они уже дошли до того, что им удобнее иметь свою надстройку над AWS.

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

— А для тех сотрудников Одноклассников, которые будут пользоваться вашим облаком, чем это будет отличаться от использования того же AWS?

— Amazon — немного другая система. Она более старая: хотя они пытаются идти в ногу со временем, делать вещи вроде AWS Lambda, использовать современный софт, там много легаси. И у нас это по-другому выглядит, потому что нет этого легаси.

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

А поскольку мы делаем конкретный продукт для нас, нам работать с ним проще, управление понятнее, и его можно естественным образом положить на то, как у нас принято делать какие-то штуки. И так не только с хостингом, но и с другими составляющими облака, где тоже уходили от универсальных решений к собственным — например, one-cloud.

— Конкретно про one-cloud вы осенью собираетесь рассказывать подробно на наших конференциях Joker и DevOops, а пока тогда расскажите кратко: что это вообще?

— Это операционная система уровня дата-центра — то есть большая распределённая система, позволяющая автоматически управлять инфраструктурой с помощью описаний задач («задача» — широкое понятие, она может включать тысячи реплик, распределённых на сервера в нескольких ДЦ). Кроме того, она может автоматически поддерживать работоспособность задачи при различных сбоях. Допустим, в простейшем случае, если сервер вылетает, то система автоматически восстанавливает необходимое количество реплик на других машинах.

— И использовать популярные опенсорсные решения вроде Kubernetes не стали использовать тоже из-за их универсальности?

— Да. Мы рассматривали и Kubernetes, и Mesos. Было ясно, что и первый, и второй в своём обычном виде не ложатся на то, что мы хотим. Мы могли бы дотянуть и тот, и другой до того, что нам необходимо. Но мы оценили работу, которую нужно было бы проделать, и работу на то, чтобы написать своё, и оказалось, что объём работы приблизительно одинаковый. В итоге решили написать своё, которое получится более удобным и понятным, более надёжным, более заточенным под нас, под наши требования и инфраструктуру.

— Поскольку про one-cloud будете рассказывать и на Java-конференции, и на DevOps-конференции, хочется узнать: эти доклады будут различаться?

— Да. На DevOops доклад будет в большей степени про процессы: как построить DevOps-процессы, когда у вас есть облака или своя система управления дата-центром, и как при этом не потерять отказоустойчивость. И об обеспечении изоляции задач на одной машине. Поскольку для такой большой распределённой системы очень важна отказоустойчивость, большая часть доклада будет именно о том, как она обеспечивается.

На Joker планируется сделать меньше про процессы обеспечения отказоустойчивости, а больше про то, как облако устроено внутри, что отказоустойчивость с этой стороны обеспечивает. Кроме того, есть идея рассказать больше об эксплуатации Java-приложений в контейнерах. Потому что наше облако — наверное, единственное, у которого сто процентов запускаемых задач написаны на языке Java, и есть опыт, полезный тем, кто на Java пишет.

— В случае с Joker ваш предварительный план доклада состоит из пунктов «содом», «гоморра» и «кишки». Там ожидать хардкора?

— Честно говоря, мне сложно судить, потому что у меня как у одного из авторов one-cloud искажённое восприятие. Мне вообще кажется, что всё очень просто, но другие люди не всегда оказываются с этим согласны. Мне самому интересно, что получится в итоге.



Обе упомянутых конференции, DevOops и Joker, состоятся осенью в Санкт-Петербурге: DevOops 20 октября, а Joker — 3-4 ноября. На сайтах обеих можно увидеть, что ещё там будет, помимо доклада Олега — и на сайтах обеих уже можно приобрести билеты.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335234/


Метки:  

[Из песочницы] Digitalization и что это за зверь

Среда, 09 Августа 2017 г. 16:58 + в цитатник
Все уже давно смирились с мыслью, что мы живём в эпоху информационных технологий и пытаемся автоматизировать всё. Смирились и забыли, живём себе и с трудом успеваем привыкать к темпу, с которым прогрессирует ИТ.

Находясь за границей на протяжении достаточно долгого времени и изучая информационные технологии с точки зрения Германия, я заметила достаточное частое упоминание в разговорах терминов «Digital business», «Digitalization». На нашем русском языке это что то близкое к информатизации бизнеса. Что стоит за этим термином и каков смысл попробую объяснить ниже.

Digitalization vs Automatization


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

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

Информатизация или, говоря красиво, Digital, как писали Gartner — это использование технологий с целью введения инноваций в бизнес модель компании и весь ее рабочий процесс с целью увеличения прибыли и конечной ценности продукта, конечно же. Что бы стало понятно, пример Digital company — это, конечно, Uber и Airbnb.

Изучая эту тему хоть и не достаточно давно, но достаточно усиленно, попробую обозначить основные отличия понятий:

  • Автоматизация — это в основном лишь способ изменения выполнения операций. Конечно, мы оптимизируем наши процессы и пытаемся выстроить новую модель бизнеса, но мы не меняем его суть (Из опыта работы в области автоматизации я могу выделить одну чудо компанию, которая при выборе ПО решила, что процессы будут менять под требования программы. Мотивация чудо, благо повезло с командой и мы делали по уму, а не по ПО).

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

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

  • Автоматизация это наше вчера и сегодня, digital это наше завтра.

Основы, которых пока ещё нет


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

Выделяют следующие компоненты диджитализации или те области на которые она влияет:

  1. (Relations with customer) отношения с потребителями
  2. (Strategy and goals) Стратигия и цели организации.
  3. (Organization structure and Human Resources) Организационная структура и управление персоналом
  4. (Culture) Культура организации
  5. (Knowledge management) Управление знанием
  6. (Processes, Infrastructure, Data) Бизнес процессы организации, инфраструктура и управление данными
  7. (Management and Evaluation metrics) Управление и контроль
  8. (Marketing and Distribution process) Маркетинг

Как мы и говорили раньше, взаимосвязь очевидна — изменение отношений с клиентами влечёт за собой как необходимость реформирования управления персоналом и культуры организации, так и изменение целей организации и позиционирования на рынке (маркетинг), изменение целей — необходимость новых способов контроля и управления, и на последок — меняем наши процессы.

Новая эра покупателей и что нас ждёт


Все на ИТ нах и в офигительных штанах

На сегодняшний день мы с вами как клиенты и потребители — главная головная боль всех продавцов товаров и услуг. Люди быстро привыкают к хорошему и с лёгкостью устанавливают новые планки на рынке: если покупать билеты, то с телефона, оплачивать безналом, а ещё лучше все тем же телефоном, поддержка должна быть 24/7, доставку хочу отслеживать, историю покупок смотреть, анализ затрат получать ежемесячно.

В Европе все эти вопросы обсуждаются не первый год и уже даже сделан ряд социологических и статистических исследований:

  • 57% потребителей считают, что все их обращения и вопросы должны решаться онлайн и только 30% компаний это под силу;
  • 64% клиентов хотят получать поддержку в реальном времени при помощи выбранного ими канала связи;
  • Возможность решения проблем онлайн, по телефону или другим способам связи увеличивают приверженность клиента более чем на 36%;
  • 78% всех потребителей принимают решение о покупке основываясь на уровне клиентского сервиса;

Эксперты так же говорят, что стоимость ответа на запросы клиента при помощи «digital technologies» составляет 12% от стоимости работы Call центров, и 56% от онлайн форумов и FAQ. Стоимость обслуживания клиента обычно колеблется от 6 до 8$, когда стоимость одного контакта, например, в социальных сетях стоит 1$.

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

Какие основные мысли мы должны запомнить из новой реальности «покупатель — Бог»:

  • наша цель — удовлетворить основные нужды потребителя — снижение прилагаемых усилий, скорость, проактивность со стороны компаний, ответственность и внимательность к потребительскому опыту (данные о процессе использования товара и впечатления потребителя), качество, человеческое отношение, надёжность
  • в нашей реальности необходимо создавать и поддерживать клиента там, где он есть: в Твитере, на YouTube, Facebook;
  • создание сообществ и тематических мероприятий для возможности коммуникации потребителей между собой, коммуникации между потребителями так же очень важны и могут принести дополнительную выгоду вашей компании.
  • умная жизнь= умный сервис ( удобный дизайн, задействование интеллектуальных технологий, дополнительная ценность для клиента).
  • необходимо контролировать и управлять «путешествием потребителя»;
  • необходимо записывать и анализировать «опыт» потребителей;
  • необходимо максимально оперативное и персональное общение с потребителем;
  • необходимо максимально оперативное и персональное общение с потребителем;
  • необходимо прислушиваться к своим потребителям, собирать данные о предпочтениях и мнениях потребителей, установить необходимые метрики для их измерения и быть готовым к изменениям, которые будут вызваны предпочтением клиента;
  • улучшение систем обслуживания клиента должны быть отражены в рекламе;
  • и при все этом, не стоит забывать о важности личного общения.

Все эти «прописные истины» говорят нам о том, что наши цели и стратегия компании должны быть скорректированы.

Курс на Digital или рекомендации по определению стратегии.


Успех процесса диджитализации, как и любого комплексного процесса зависит от его стратегии и концепции. Если мы говорим о комплексном изменении бизнеса и всей модели работы компании, то стратегия нам просто необходима, попробуем свести все рекомендации в один список:

  • Начинайте разработку стратегии с конечной цели и планируйте изменения от нее — успешный процесс диджитализации коренным образом может изменить внутренние процессы и даже противоречить текущим ограничениям.

  • Непрерывное взаимодействие с клиентом — на всех уровнях и этапах работы мы должны поддерживать контакты с нашими клиентами и быть в курсе его текущих потребностей.

  • Создавайте новые возможности — в новой сфере необходимо создавать собственные возможности и технологии, чтобы создать центр передового опыта с квалифицированным персоналом и новыми бизнес-процессами.

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

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

В данном посте представлена далеко не вся информация, на сегодняшний день уже практически дописан пошаговый план диджитализации, так что в зависимости от реакции буду продолжать писать или нет. Спасибо за внимание.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335264/


Метки:  

Как математическая библиотека КОМПАС-3D превратилась в C3D Toolkit для разработчиков САПР -> часть 1

Среда, 09 Августа 2017 г. 16:44 + в цитатник
В предыдущих постах мы рассказывали о том, как разрабатывается и тестируется САПР КОМПАС-3D. Дополнительно запущен цикл статей по разработке приложений с использованием API КОМПАС-3D. Пришло время рассказать о «начинке», которая управляет всеми построениями в КОМПАСе – ядре геометрического моделирования C3D или просто геометрическом ядре C3D.


Автолестница пожарная АЛ-30 (изготовитель: ООО «Пожарные Системы»)

Зачем нужно геометрическое ядро, когда имеется доступ к API CAD-системы?


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

Особенности работы с интерфейсом прикладного программирования прописываются в технической документации. Здесь же указывается, какие значения необходимо подавать на вход конкретной функции, чтобы получить на выходе корректные значения согласно предназначению данной функции. То есть API позволяет абстрагироваться от реализации отдельных программных блоков при разработке приложений:


Работа с API-интерфейсом по принципу «чёрного ящика»

Благодаря наличию в КОМПАС-3D собственного API базовая функциональность системы с течением времени была дополнена приложениями для проектирования радиоэлектронной аппаратуры и электрооборудования, деталей машин, трубопроводов, металлоконструкций, зданий и сооружений различного назначения.

Но использовать API САПР не всегда удобно и целесообразно. Дело в том, что при обращении к геометрическим функциям ядра напрямую разработчик избавляется от необходимости взаимодействия с промежуточными звеньями CAD-системы, такими как графический интерфейс, спецификации и пр. Поэтому одинаковая геометрия в ядре создаётся быстрее, чем в API САПР. Также использование геометрического ядра позволяет разработчикам инженерных приложений сохранять в секрете придуманные ими ноу-хау. Например, особенности построения сложных геометрических моделей могут быть легко скрыты от внимания пользователя.

Большинство современных САПР базируются на дереве построения 3D-модели, а значит каждая новая операция приводит к перестроению всего дерева, поэтому с помощью ядра намного проще проводить итерационные построения, в частности создание зубчатых передач:


Коническая передача, построенная приложением «Shaft» без использования геометрического ядра: множественные операции построения скрыты в макроэлементе


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

С применением в разработке геометрического ядра уменьшается вероятность поломки модели при смене пользователем версии приложения, да и в целом повышается стабильность работы программы при непредсказуемых действиях пользователей. А включение математической библиотеки в основу разрабатываемого решения позволяет обеспечить независимость от существующих программ. Как минимум, это означает, что не нужно тянуть за проектом дистрибутив сторонней (часто тяжелой) системы и производить лицензионные отчисления за использования связанной САПР. Тем не менее, последнее утверждение нельзя считать весомым аргументом, так как разработчики приложений часто ориентируется на аудиторию конкретной CAD, CAM или CAE системы, иногда достигающей значения в десятки и сотни тысяч активных пользователей.

Геометрические и игровые ядра


Набор геометрических функций в САПР образует в совокупности геометрическое ядро системы, которое отличается от игрового движка с реалистичной 3D-графикой. Наиболее наглядно это демонстрируется через аналогию с графическими редакторами. Как известно, часть из них работает с растровой графикой, основанной на точках. Другие редакторы оперируют векторной графикой, которая базируется на кривых линиях. Точно также в 3D-приложениях существует полигональная графика, которая основывается на положении точек в пространстве (из них строятся полигоны), и сплайновая графика, представляющая собой сочетание математических формул и уравнений.

Выражаясь в терминах САПР, можно сказать, что полигональная графика строится на фасетном представлении геометрии. Такое же представление используется в игровых движках и в различных анимационных пакетах для создания спецэффектов кино:


Фасетное представление геометрии 3D-модели

Математически точное описание 3D-модели задаётся граничным представлением. Его основная особенность в том, что для представления формы геометрической модели используется набор граней, проходящих по границе, которая отделяет внутреннее пространство моделируемого объекта от остальной части пространства. Как вы уже, наверное, догадались – именно это представление используется в геометрических ядрах:


Граничное представление геометрии 3D-модели

Но тогда почему для геометрического ядра не подходит полигональная графика?


Можно выделить три основных причины:
Масштабируемость. Любой объект необходимо беспрепятственно увеличивать и уменьшать. Дефекты геометрии неуместны.


Охотничье хозяйство в натуральный размер. При увеличении модели все грани сохраняют форму (Картинка кликабельна)

Гладкость. Сетка из треугольников для работы с чертежами не подходит — на чертеже нужны гладкие и чёткие контуры, а сетка создаст визуальную грязь.


Пример передачи фасетной модели в чертёж. Видно как сливаются места сгущения сетки (Картинка кликабельна)

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


Обработка модели в CAM-системе Esprit

В действительности же причин значительно больше, но это – профессиональные тонкости.

Невероятно, но факт: современные системы проектирования (и КОМПАС-3D – не исключение) работают с двумя представлениями геометрии. Граничное представление используются в процессе моделирования, после чего производится расчёт триангуляционной сетки и строится полигональная модель, которая затем отправляется в видеокарту для отрисовки визуальной сцены. На данном этапе в процесс может вмешаться ядро визуализации, например C3D Vision, которое отвечает за управление отрисовкой модели с использованием средств математической, программной и аппаратной оптимизации. Подробнее об этом мы расскажем в следующих статьях.

Сложный выбор: купить ядро или написать собственное?


Каждый разработчик инженерного программного обеспечения рано или поздно оказывается перед выбором: писать ли необходимые математические алгоритмы самому или приобрести готовые компоненты на стороне? В истории АСКОН использование сторонних модулей рассматривалось в 1995 году, когда обсуждалась разработка КОМПАС-3D. Тогда был выбран тернистый пусть самостоятельного написания геометрических функций, в основе которых лежит довольно сложная математика. Подробнее ознакомиться с ней можно, прочитав книгу Николая Голованова по геометрическому моделированию:


Оглавление и обложка книги «Геометрическое моделирование» Н.Н. Голованова (Картинки кликабельны)

Мало кто знает, что позднее, в 2000-х годах, в АСКОН повторно рассматривался вопрос использования стороннего математического ядра для работы с 3D. Было произведено тестирование доступных на рынке CAD-компонентов и принято стратегически важное решение о продолжении разработки собственного геометрического ядра. Оно получило имя C3D, что является сокращением от внутрикорпоративного названия проекта «Core3D». Сегодня это ядро успешно используется не только внутри АСКОН, но и в проектах других разработчиков систем автоматизированного проектирования в России и за рубежом.

Продолжение следует. Вторая часть статьи будет посвящена непосредственно геометрическому ядру С3D, его истории, возможностям и опыту применения при разработке 3D-приложений.

Аркадий Камнев, Менеджер по продукту C3D.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334814/


Linux Kernel Extension for Databases

Среда, 09 Августа 2017 г. 16:37 + в цитатник


Александр Крижановский ( krizhanovsky )


Сегодня буду рассказывать про внутренности базы данных, про внутренности ОС и о том, что происходит на стыке. Когда я говорю про базу данных, я имею в виду в основном ввод/вывод, управление памятью и обработку транзакций. Это совершенно не про SQL, не про индексы, не про блокировки и т.д. Только ввод/вывод, управление памятью и транзакции.

В тех местах, когда я буду упоминать про базы данных, я буду ссылаться на InnoDB, которая мне наиболее знакома.



Если мы посмотрим на движок транзакционной базы, мы увидим примерно такую же картинку. У нас есть буфер pool, в нем живут странички индекса, странички данных. Все эти странички выводятся через транзакционный лог, когда они изменились, проходит это все через планировщик ввода/вывода и в ту, и в другую сторону. Планировщик ввода/вывода, когда он считывает что-то с диска, он делает read ahead. Все это проходит через файловую систему, но это дальше, на диске.

Добрый вечер! Меня зовут Александр Крижановский, я работаю в 2-х местах. В одном мы занимаемся разработкой высокопроизводительных приложений на заказ, консалтингом, в основном, это система обработки сетевого трафика и базы данных. В другом проекте – в Tempesta Technologies (это филиал NatSys Lab) – мы занимаемся разработкой open source application delivery controller. Это гибриды из средств безопасности, веб-акселераторов и т.д., которые помогают вам доставлять контент быстро и надежно.


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



Тогда, это много лет назад, у меня стояла задача построить очень быстрый сторедж для истории Instant messenger’а. Сторедж этот должен был держать сообщения пользователей по ключу из 3-х компонентов: отправитель, получатель и временами метка сообщения. Требовалась большая производительность. Начинали с того, что нам вообще консистентность не важна, мы хотели это все делать на файловом сторедже, а потом пришли к тому, что как-то нехорошо терять сообщения пользователей, и мы захотели какую-то consistency. И поскольку мы начинали с файлового стореджа, подумали, что 2-3 месяца достаточно, чтобы что-то такое сделать на файлах. Заложили срока очень мало, и в результате надо было это все быстро делать.




Сегодня буду рассказывать про внутренности базы данных, про внутренности ОС и о том, что происходит на стыке. Когда я говорю про базу данных, я имею в виду в основном ввод/вывод, управление памятью и обработку транзакций. Это совершенно не про SQL, не про индексы, не про блокировки и т.д. Только ввод/вывод, управление памятью и транзакции.

В тех местах, когда я буду упоминать про базы данных, я буду ссылаться на InnoDB, которая мне наиболее знакома.



Если мы посмотрим на движок транзакционной базы, мы увидим примерно такую же картинку. У нас есть буфер pool, в нем живут странички индекса, странички данных. Все эти странички выводятся через транзакционный лог, когда они изменились, проходит это все через планировщик ввода/вывода и в ту, и в другую сторону. Планировщик ввода/вывода, когда он считывает что-то с диска, он делает read ahead. Все это проходит через файловую систему, но это дальше, на диске.



Теперь давайте посмотрим на то, как устроена подсистема ввода/вывода и виртуальной памяти в Linux. Вот, слева. И в принципе, в ОС. И мы видим очень-очень похожую картинку, т.е. у нас есть page cache, там хранятся какие-то странички, сбрасываются они через файловую систему, через VFS к файловой системе. Вместе с файловой системой обычно поставляется транзакционный лог и все это тоже проходит через планировщик ввода/вывода, и там тоже разные умные вещи происходят.



Традиционно, базы данных строились на системном вызове O_DIRECT. Это достаточно старая выжимка из письма Линуса. В общем, не приветствуется это разработчиками ОС, и у нас достаточно долго есть недопонимание между разработчиками ОС и баз данных – что должно быть.



В то время я решил, что мы не будем пытаться выкинуть ОС, как большинство разработчиков баз данных, а будем максимально использовать ее интерфейс, поскольку времени у нас мало. У нас есть замечательный системный вызов mmap, который нам поможет. У него есть все необходимые нам фичи, которые мы видели сейчас на левой картинке. Во-первых, он вытесняет странички. Когда страничка вытесняется, она пишется на диск, и она пишется атомарно, файловая система это обеспечивает. Далее mmap как-то в бэкграунде сбрасывает странички, и у нас получается персистентность. Ввод/вывод управляется ОС, у нее есть разные продвинутые планировщики ввода/вывода – это тоже нам хорошо, и у нас есть такая приятная фича, что мы даже получаем индексы бесплатно.



Давайте посмотрим на последнюю фичу. Mmap – это просто непрерывная область памяти, достаточно большая. Соответственно, есть виртуальные адреса, есть физические, и все обращения в память у нас, которые происходят, должны ходить через транзакцию виртуального адреса в физический. Для этого у нас используется таблица page table. Она занимается этим резолвингом. У нас есть сверху ключ 48-битный, это адрес. Из него используется только 36 бит. И здесь мы проходим, откусываем по 9 бит за раз от этого ключа и проходим по дереву. У нас получается некий такой radix tree.



Если эту картинку пересмотреть, то будет примерно то, что показано слева. У нас первые 9 бит ключа определяют индекс в этом массиве, потом мы переходим здесь по указателю на следующий и т.д. Структура называется radix tree. И в целом, если мы строим какое-нибудь бинарное дерево в оперативной памяти, обычно бинарное дерево, скажем, какое-нибудь STL map, который использует красно-черное дерево, у нас на каждом поиске элементов, если мы спускаемся с дерева и хотим пойти до зелененького элемента из синего, то мы должны в общем случае разрезолвить адрес и, соответственно, пройти все наше большое дерево, сделать 4 обращения к памяти. Получается, что на то, чтобы пройти каждый элемент нашего прикладного дерева, мы должны пройти еще дерево таблицы страниц.



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



Если мы на это более внимательно посмотрим, то это на самом деле не что иное, как просто обычный СИ-шный массив, т.е. большой СИ-шный массив – это на самом деле дерево.



Мало что, наверное, с этим можно сделать, но здесь интересно то, что виртуальная память совсем нам не дешева. Первое, о чем хочу сказать – это 3-ий буллет – о том, что если если мы будем использовать виртуальную память как просто индекс из коробки, то если мы будем использовать ключи с плохой локальностью, т.е. сильно распределенные ключи, у нас все будет очень долго, потому что мы будем использовать очень много памяти. Т.е. один элемент мы храним, а используем целую страницу там, где он лежит, и каждый элемент этого дерева – это страница. Дерево – очень дорогое.

У нас это дерево кэшируется в TLB. TLB маленький и, к сожалению, мы в сontext switch’ах должны вообще инвалидировать полностью кэш первого уровня, потому что виртуальные адреса у нас могут быть одинаковые и, соответственно, у нас вылетают все эти адреса. Но хорошо то, что user-space/ kernel-space/сontext switches он оставляет кэши нетронутыми, потому что ядро и user-space работают в одной таблице страницы.



Собственно, на тот момент, когда я начал разбираться с mmap, я понял следующую вещь – о том, что, во-первых, если мы используем большие данные, нам нужно максимально держать пространственную локальность, т.е. нельзя просто так за-mmap’ить большую область и как попало использовать, нужно максимально локально ключи использовать. Большие map’ы достаточно дороги, потому что если вы mmap’ите большую область, вы тратите много на таблицу страниц, т.е. вся эта область должна как-то адресоваться.



На самом деле я далеко не первый, кто, вообще, попытался переиспользовать механизмы ОС с помощью mmap. Мы видим, что еще 35 лет назад люди задавались этим же вопросом – о том, что как-то нехорошо получается, что, вроде как, у нас все механизмы есть, но операционные системы не удовлетворяют требованиям разработчиков баз данных.

Сформулировал Michael Stonebreaker эти требования, они достаточно интересные, и интересно, что фактически все, кроме последнего, до сих пор актуальны. Т.е. за это десятилетие процессы стали достаточно легкими, у нас появились треды, у нас много всего изменилось, появился mmap (т.е. эта статья еще до появления mmap). Остальные, в принципе, более или менее, актуальны. Т.е. первое, что когда мы делаем mmap, вытесняем, мы не знаем, когда какая страница вытеснится, в каком порядке и т.д.

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

Последние 3 проблемы сейчас более или менее решены, а первые 3 как не были решены, так и не решились. Давайте с конца все это посмотрим.



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



Соответственно, нам здесь здорово помогает системный вызов fallocate. Если мы создаем большой файл, если мы делаем большую запись в файл, то мы можем пререзервировать последовательную область на диске и писать туда данные.

Поскольку у нас файловые системы не только аллоцируют данные extent’ом, но они их еще и адресуют, большинство файловых систем индексируют свои блоки через деревья, через B-tree, хэштрай и, чем больше блок данных они индексируют, тем ниже это дерево. Соответственно, если они индексируют большие extent’ы, то деревья получаются достаточно низкими. Если мы аллоцируем пару файлов fallocate, то у нас еще меньше индекс. Т.о., по сути, у нас дерево, которое есть у файловой системы для адресации блоков, очень низкое, и эта проблема нивелируется тоже.



Теперь самое интересное – это то, как обрабатываются транзакции. Здесь схематично попытался нарисовать, как выглядит transaction processing в InnoDB. Давайте рассмотрим, что здесь у нас есть две грязные странички, у которых изменяются 2 записи красным цветом. И самое важное для нас, что InnoDB использует политику т.н. steal и no-force, это значит, что эти странички могут быть в любой момент сфлашены с диском, т.е. до момента коммита. Это значит, что они воруются, это steal-стратегия, а no-force говорит о том, что когда у вас проходит коммит, необязательно, что у вас будут зафиксированы все ваши данные на диске. Т.о. мы используем undo, redo log’и для того, чтобы откатить. Undo log – откатить сфлашенные до коммита данные, транзакцию, которая еще не закоммитилась, и redo – для того, чтобы восстановить.

Здесь еще интересно, что есть undo log – это основа, на чем работает мультиверсионность. И он хранит старые версии записи. В целом для базы данных ее транзакционный уровень ввода/вывода должен знать о record’ах, т.е. мы не можем реализовать достаточно гибкую стратегию фэшинга без знания семантики данных, которые мы храним, без знания record’ов.



В принципе, я уже сказал о том, что мы не можем гарантировать, когда какая страница будет записана, не можем говорить о записях. И давайте посмотрим, например, что у нас будут какие-то две транзакции, которые совершенно разные страницы модифицируют, но на одной из страничек они модифицируют разные записи. У нас Linux VMM не знает о record’ах, соответственно, когда у нас первая транзакция коммитится, мы можем сказать, что у нас была изменена 3-я страничка. Но мы ее должны сфлашить. Допустим, мы ее флашим, эти первые 3 страницы, которые были изменены первой транзакцией. Но, когда мы флашим эту страницу, мы не знаем, успела ли другая транзакция сделать изменения в 3-й странице или нет. И мы вместе с первой транзакцией можем сфлашить изменения 2-ой транзакции, а можем и не сфлашить. И самое плохое, что мы этого вообще не знаем и даже не можем узнать.

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



Первое, что хочу сказать о файловых системах – популярные файловые системы, которые большинство используют, это т.н. log-расширенные файловые системы. Т.е. есть обычная файловая система, к ней припиливается лог. Когда мы делаем запись, мы сначала пишем в транзакционный лог и потом уже пишем на диск. Соответственно, у нас получается двойная запись обязательно. Во-первых, лог транзакционный пишется последовательно, поэтому нам хорошо, он маленький, он последовательный, а во-вторых, поскольку мы уже записали в лог, мы можем отложить запись изменений, забатчить их и большим куском все вместе опустить.



Проблема двойной записи нравилась не всем, и люди делали попытку вообще уйти от двойной записи. Они говорили: «OK, давайте мы откажемся от структуры файловой системы и всю ее построим как один большой транзакционный лог. У нас изменились данные, мы их допишем в конец последовательного лога, который все растет и растет дальше. И изменяется кусок файла, мы его дописываем в конец. Теперь у нас inode, который ссылается на изначальный наш блок, должен быть изменен, т.о. мы тоже должны его копировать туда в конец транзакционного лога. И поскольку у нас теперь inode’ы плавают по диску, мы должны еще где-то держать карту inode’ов, которую тоже как-то апдейтить с этими указателями на inode’ы в конце. И получается достаточно сложная структура со сложным менеджментом, показывающая очень плохую производительность. Например, Nilfs до сих пор в ядре Linux есть, ее можно взять и запустить попробовать.



Продолжением этой идеей (что-то между первыми и вторыми) стали Copy-On-Write файловые системы. Это современный ZFS и BtrFS. Они используют такой же подход. Поскольку обе файловые системы позволяют снэпшотить, то они используют следующее свойство. Допустим у нас есть желтенькое дерево изначально, потом мы должны добавить элемент 19. Мы берем, копируем этот блок, дописываем к нему 19. Теперь мы должны ссылаться на этот блок из root’а. Root мы тоже копируем и приписываем ссылку. Эти оставляем. И в этот момент у нас остается 2 элемента, которые у нас когда-то освободятся. За счет этого мы можем делать снэпшоты. Здесь у нас похожа идея на log-структурированную файловую систему, т.е. новые изменения мы просто дописываем дальше.

И здесь получается следующее свойство. Если у нас есть файл базы данных, который примерно одного размера сохраняется, например, у вас есть 100 тыс. пользователей/клиентов, которым вы иногда изменяете записи и т.д., но примерно у вас файлы в базе данных будут одинаковые, медленно расти, но будет высокий update. Такая файловая система будет все время аллоцировать место на диске и все время будет крутить диск, и с фрагментацией тут тоже будут проблемы, потому что эти 4 блока были последовательны на диске. После того, как мы запишем вот эти блоки, слинкуем, у нас будет дырка на диске, проблема с локальностью здесь есть. С другой стороны, если мы все время дописываем новые и новые данные, то такая файловая система имеет место быть. Она пишет только один раз данные, она не пишет их 2 раза на диск. Поэтому, наверное, BtrFS лучше для OLAP-нагрузок, когда вы периодически выгружаете большие объемы данных на диск и выгружаете их последовательности. Если же у вас идет большой update (OLTP-нагрузка), то лучше классическая файловая система обычная.



Последнее о чем хотел упомянуть – это FreeBSD файловая система. Она говорит о том, что мы можем вообще не использовать никакие логи, а можем аккуратно делать update. Если мы, например, хотим добавить новый блок в файл, то мы сначала аллоцируем блок, где мы его аллоцировали, положили, и только потом мы должны записать ссылку на него в inode. Если у нас где-то посередине отвалится, ну, мы потеряем первый блок, но консистенция останется. С другой стороны, если мы сначала изменим inode, который ссылается на новый блок, а блок еще не выделен, то у нас свалится консистентность файла. Так она работает, но, понятное дело, что файловая система, опять же, не знает никаких данных, она может сохранять только консистентность своей структуры, она не может сохранять консистентность данных. В принципе, файловые системы XFS и EXT4… XFS позволяет только мета-дату делать, EXT4 можно настроить, чтобы она данные тоже логировала, т.е. EXT4 позволяет вам более консистентные данные хранить.



И мы подобрались к вопросу: можно ли все-таки механизмы баз данных выкинуть и использовать вместо них файловую систему? Yves Trudeau из Percona написал замечательный блог о том, как он попытался вытянуть doublewrite buffer и заменить его транзакционным логом файловой системы. И блог этот, насколько помню, вообще, в 2-х частях. Первая часть о том, что все замечательно, все хорошо получилось, вторая – о том, что ничего не получилось.

Кстати, мы выложили в открытый доступ видеозаписи последних пяти лет конференции разработчиков высоконагруженных систем HighLoad++. Смотрите, изучайте, делитесь и подписывайтесь на канал YouTube.

Проблема в том, что мы не можем писать большие данные. Т.е. давайте рассмотрим, что мы пишем сейчас с вами… Делаем большой write, один системный вызов вызываем, который должен записать нам 3 блока. Первый пишем, второй пишем хорошо, потом мы отваливаемся. Нам файловая система не откатит изменения первого. Транзакционный лог файловой системы – это очень небольшой файлик, маленький. С другой стороны мы можем вызвать write на много-много Гбайт, например, какой-нибудь большой image blu-ray попытаться сохранить. И нет у нас места для того, чтобы все эти данные где-то сохранить. Мы можем саллоцировать большой файл и записывать там данные. Нам тоже негде все это сохранить. Файловая система максимум, что может, даже в максимальном варианте EXT4, которая должна обеспечивать консистентность данных – мы какую-то часть из данных, переданных в write VM, консистентно запишем, а какую-то – нет. Что-то у нас откатится, а что-то нет. Вообще говоря, это профанация – консистентность данных файловой системы.



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



Давайте еще посмотрим, как у нас вытесняются данные, флашатся из памяти на диск. Linux работает с двумя списками – активный/неактивный. Если приходит к нам какая-то новая страничка, мы почитали ее в памяти, либо поизменяли, и пока мы ее изменяем, она находится в active list, а как только она устаревает, она вытесняется в inactive list по timeout’у. Если она сколько-то пробудет в inactive list, отсюда она флашится на диск, и отсюда она может забираться аллокатором. Проблема здесь в чем? Что это две линейные структуры данных с последовательным доступом. У нас памяти может быть очень много, современные сервера — 128/512 Гбайт оперативки, делим это все на 4 Кбайта и получаем уйму страничек, которые будут лежать в линейном списке. Соответственно, если у нас доступ к нашим данным, к памяти все время меняется, мы меняем то одни странички, то другие пачкаем, у нас в эти списки оно добавляется, inactive список тоже может у нас пухнуть по каким-то своим правилам. В какой-то момент мы можем брать страничку, снова к ней обращаться, она снова сюда передернется. И это множество все время у странички может циркулировать между этими списками, когда страничка все-таки флашится на диск, она может быть снова поднята с диска при обращении и т.д. В общем, когда ядру Linux не хватает памяти, когда ему приходится сканировать эти списки, все становится очень медленным. Кстати говоря, kswapd – однопоточный демон, плюс он должен лочить эти списки, когда он по ним бегает, для того чтобы сохранить консистентность структуры данных относительно изменений, которые делают другие процессы по вставке и извлечению страничек. Ну и, в общем, все очень плохо.



Есть у нас несколько системных вызовов, которые нам помогают синхронизировать принудительно данные из открытого файла, скажем fsync, либо из mmap. Но проблема в том, что если мы внимательно посмотрим на все эти вызовы, у нас есть адрес, есть длина, offset, nbyte. Мы можем какой-то непрерывный range сбросить, мы не можем сказать: «Пожалуйста, сбрось нам 1-ую, 3-ю и 5-у странички». Так мы не можем. Если мы сбрасываем и делаем один большой write, то мы не можем его записать атомарно. И мы не контролируем, когда ядро Linux скинет определенную страничку – может быть до этого sync’а, а может быть после sync’а. Когда мы mmap’им файл, мы вообще не знаем ничего о том состоянии файла на диске, какие данные синхронизированы, а какие не синхронизированы. Это плохо.



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



Это некоторая сумма о том, что только что сказал. Первое – о том, что мы вытесняем, а когда мы вытесняем, мы не знаем, можем только немного влиять. Есть полная синхронизация файла и это, кстати, причина, почему транзакционный лог баз данных хранится в отдельном небольшом файле, потому что мы можем полностью сделать fsync на этот файл, полностью его синхронизовывать, потому что у нас нет другого выбора, как синхронизировать какую-то область, например. Почему он в table spase не хранится. Залоченые списки сканируем, это все плохо очень.



Давайте пройдемся по ресерчу, который делается в области файловых систем. Прежде всего, это Reiser4. Они добавляли транзакционность, но опять же транзакционность для небольшой записи. По-моему, это 4-32 Кбайта, атомарность давали. У них есть какая-то поддержка транзакций, но большие данные нельзя сохранить консистентно, с гарантией.



BtrFS дает нам интерфейсы по транзакциям. Мы можем сказать, что начать транзакцию, начать операцию с файловой системой, по-моему, это не только read, write в определенный файл, но это всякие перемещение файлов, удаления и т.д. Потом закончить транзакцию. Здесь есть проблемы, и это интерфейс, не рекомендованный к использованию в том, что если мы начинаем транзакцию, потом наш процесс подыхает, то больше никто не сможет обратиться к этим файлам, к которым он залочился. Т.о. транзакция не откатится.



Есть Windows TxF. Она, вроде, была в какой-то версии Windows, наверное, даже сейчас есть. Она объявлена как deprecated, тоже, насколько помню, по тем же самым причинам, что и в BtrFS. И есть еще ресерчевская достаточно свежая файловая система, которая позволяет вам на уровне самом высоком, абстрактном, делать транзакционные системные вызовы над файлами в семантике транзакций. Тоже начинаем транзакцию, коммитим, откатываем и т.д.



Далее, у нас есть еще ОС 2009-го года, которая говорит о том, что «почему бы нам, вообще, не сделать все операции в ОС транзакционынми?». Т.е. любую последовательность системных вызовов мы можем поставить под транзакцию, любую откатить, и для этих целей там патчится абсолютно все. Все структуры данных, когда вы меняете. Например, у вас есть структура task_struc t, если вы изменяете процесс, например, изменил какие-то данные по файловым дескрипторам или еще чему-то, вы копируете всю эту структуру, помечаете ту как old copy, новую как новую копию, и работаете с этими копиями. Потом их удаляете. И в целом вы можете это откатить.



Более интересный для нас пример – это оказался msync-проект. Он делает достаточно маленькие вещи, он просто дает транзакционный интерфейс к mmap’у. Он позволяет вам за- mmap’ить область памяти с новым флагом MAP_ATOMIC, msync патчат, который позволяет синхронизировать только измененные данные, причем не в последовательности, а только те, которые были недавно изменены. Добавляют REDO logging и патчат сброс страниц. Т.е. достаточно небольшие изменения, но которые позволяют нам атомарно работать с mmap’ленной областью.



Последний пункт, который у нас был, который адресовал Michael Stonebreaker – это о том, что у нас файловые системы неструктурированные. На самом деле у нас есть файловые системы, которые структурированы, которые дают вам Record-oriented интерфейсы. И в RMS такой есть, по-моему, это было в IMB-mainframe’ах, соответственно, в mainframe’овских файловых системах у нас есть файловые системы, которые вы можете открыть sysopen – специфичными системными вызовами. Т.е. не такими как open, read, write в Linux, а используя специальные системные вызовы для открытия файла, для последовательного доступа, для доступа по индексу и т.д.

На самом деле, это получается у вас, когда вы закрываете файл, у вас все это сбрасывается обязательно. На самом деле это выглядит как база данных, она пахнет как база данных, она по сути внутри и есть база данных. У вас есть индекс, у вас есть транзакция, у вас есть интерфейс этого добавления записи, прохода по записям и т.д. По сути, это встраиваемая база данных, которая сделана на уровне ядра VMS. И, вообще говоря, это не 80-ые годы, это современная вполне вещь, и сейчас можно скачать документацию по этому, это документация современной ОС.



Подобрались уже к нашему решению. Мы тоже делаем базу данных, но нам база данных понадобилась, поскольку мы делаем веб-акселератор, то акселератор должен хранить контент страниц. Есть, например, Apache Traffic Server, который реализует некоторое подобие базы данных, он не в каждом отдельном файле хранит табличку, а в специально алоцированном спейсе, который может разбивать эффективно и адресовать.

Мы также используем базы данных, т.е. основное, для чего мы используем TempestaDB – это файловый кэш, ну, кэш ответов сервера. Там же еще у нас хранятся правила фильтра, заблокированных клиентов, там же будут храниться сессии пользователей и т.д.

Сама Tempesta работает внутри softirq. Это полностью ядерное решение, и сейчас мы начали работать над тем, чтобы открыть эти интерфейсы и сделать что-то более общее, что можно было бы использовать в новых приложениях для базы данных. Нам самим сейчас понадобились новые интерфейсы для доступа к базам данных, для того чтобы можно было удобно управлять веб-кэшом и, соответственно, нам стало не хватать ядерных баз данных, к которым тяжело получить доступ из user space. Это все сейчас находится только в разработке, сейчас в отдельной ветке на github’е это лежит.



Давайте посмотрим, что делается, как все это хозяйство используется. У нас есть user space-утилитка, которая вам позволяет делать какие-то queries’ы в базу данных, отрывать таблички и т.д., т.е. достаточно проста. Остальное все, что делается – это на уровне ядра в базе данных у нас фильтр хранит правила фильтрации, здесь хранится веб-кэш, будет храниться логирование.



Тот интерфейс, который сейчас есть в мастере – это такой интерфейс, т.е. вся эта база данных лежит у нас внутри ядра, и мы используем netlink-mmap-интерфейс для того, чтобы передать запрос через сокет в ядро. Ядро здесь крутит запрос и потом отдает результаты в user space. Проблема в том, что сам по себе netlink-mmap может любой ядерный буфер смапить вам в user space, т.е. мы с помощью zero-copy можем передать все данные из ядра в user space. Проблема заключается в том, что в базе данных у нас много всего лежит. Если вы дадите запрос, например, «дайте мне все ответы сервера за какой-нибудь период или к какому-нибудь индексу», мы не можем просто взять и, как бы, страницы базы данных замапить в user space, потому что у нас в этих страницах будут и записи, которые соответствуют запросу, и записи, которые не соответствуют, во-первых. Во-вторых, эти записи могут меняться вот прям сейчас в онлайне. И мы поступаем так, что мы здесь, в сторонке, аллоцируем новые странички, туда собираем результаты выполнения запросов, а потом эти странички мы мапим без копирования в user space. Нам захотелось все-таки быть совсем без копирования, и чтобы у нас и user space процесс, и сама Tempesta работали с одним буфером внутри ядра Linux как с одной общей базой данных, т.е. у нас получается многопоточная база данных с одинаковыми данными.



И сейчас немного про то, как мы строимся. Во-первых, мы используем только большие страницы. Когда ОС грузится, мы откусываем от нее область памяти, большую непрерывную, так же, как делает huge tdbfs. Потом в нее мы мапим все наши данные, т.е. поскольку Tempesta – это полностью ядерное решение, оно работает в softirq. Т.е. сами треды обработки и клиентских запросов – это отложенные прерывания, спать мы там не можем, на диск мы не можем, поэтому есть жесткое требование о том, что вся база должна быть in memory, она должна быть персистентная, должна быть консистентной, но вся должна помещаться в память, чтобы пришедший запрос мог сразу отработать. Сбрасываемся мы только в отложенных нитях.

Припиливается сейчас новая файловая система, которая должна дать интерфейс к TempestaDB. Собственно, через этот интерфейс у нас будет свой mmap, похожий на msync. Используем мы сейчас стратегию no-steal force либо no-force. No-steal, напомню, это значит, что страницу мы не можем сбрасывать на диск до тех пор, пока нет коммита. А forсe, no-forсe значит то, что если у нас forсe-стратегия, то тогда, когда проходит коммит, мы обязаны все sync’ать на диск. Если no-force, то коммит прошел, но sync’а может не быть.



Давайте посмотрим, что происходит. Во-первых, как это все организовывается сейчас. Есть сегмент страниц этих больших, которые аллоцируются. Мы от него отрезаем небольшую область вначале. Это транзакционный сегмент, здесь у нас живут интерфейсы mmap, виртуальной файловой системы тонкой, и прикладной уровень ходит через эти интерфейсы. Получается, что вся база данных мапится в user space через mmap, на уровне user space виден как индекс, так и данные. И выводится отдельный менеджмент в потоке, который занимается синхронизацией.



Смотрите, если у нас приходит какая-то транзакция, которая изменяет 2 странички и изменяет 3 записи. Мы изменили в huge pages данные, мы их не флашим, т.е. все это встраивается в систему VMM Linux’а, но эта специальная область не сбрасывается в бэкграунде.



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



Теперь, когда коммит прошел, мы уже флашим все данные.



В другом сценарии, если мы пишем, делаем какую-то транзакцию из ядра Linux, то все данные, которые мы здесь изменяем, мы не можем их сбросить внутри softirq. Мы должны попросить отдельный поток, который нам их сбросит.



Вытеснение из кэша. Поскольку мы должны реализовать веб-кэш, в котором записи должны устаревать, мы еще прикручиваем и вытеснение из кэша. Вытеснение из кэша работает через наш вспомогательный поток и также через сброс через транзакционный лог, т.е. когда у нас есть запись в страничке, мы уже знаем, что она уже закончена, мы ее можем сбросить на диск.



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

В TempestaDB у нас есть несколько режимов работы, если у вас очень большой контент, который вы копите в кэше, то вам имеет смысл, чтобы каждый процессор ходил в удаленную ноду. Пускай медленно, но мы храним данные только 1 раз. С другой стороны, если вам нужна очень высокая производительность, но данных немного, то мы можем скопировать данные на разные процессорные package’и, в их локальную память, и каждый процессор будет работать достаточно быстро с их локальной областью.



Собственно, это режим, когда у нас есть памяти мало, контента много, мы его разбиваем на разные участки, когда приходит запрос, он шардуется на тот или иной процессорный package.

И репликация – это когда у нас полностью весь контент копируется.



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



Это то, как работает наше дерево, что из себя представляет burst hash trie. Это небольшая hash-табличка, всего из 16-ти элементов. Когда приходит некоторый ключик, мы из него высчитываем hash, берем последние 4 бита, и 4 бита нам определяют место в этой hash-таблице. Сейчас hash-таблица пуста, поэтому прямо здесь будет храниться наш ключ, т.е. как в массиве.



Далее, теперь если у нас приходят еще одни значения, то мы уже маленькие значения можем напихать в бакет, не больше одной страницы, работаем дальше с ним как со списком обычной hash-таблицы.



Потом, когда заканчивается у нас место в этом бакете, у нас происходит взрыв бакета.



Это значит, что мы выращиваем 2-ой уровень hash-таблицы. Если у нас происходит коллизия, мы берем по первому элементу индекс в первом узле, по второму элементу мы определяем 2 других, т.е. это примерно работает как radix tree, только у него не константная высота. И мы должны перебросить все значения в новые бакеты.



Теперь про транзакции. Когда у нас происходит изменение, оно пишется у нас в транзакционный лог внутри узлов дерева. Все это пишется в транзакционный лог, сами record’ы тоже пишутся транзакционный лог и, когда добавился полностью record, то индекс вместе с данными последовательно ложится на диск.

Всем спасибо!

Контакты


» krizhanovsky
» ak@tempesta-tech.com
» Исходный код проекта
» Блог

Этот доклад — расшифровка одного из лучших выступлений на профессиональной конференции разработчиков высоконагруженных систем HighLoad++.

Сейчас мы уже вовсю готовим конференцию 2017-года — самый большой HighLoad++
в истории. Если вам интересно и важна стоимость билетов — покупайте сейчас, пока цена ещё не высока!

Кстати, мы обязательно позовём в докладчики Александра Крижановского — на сегодняшний день это один из лучших профессионалов отрасли.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335260/


Как избежать ошибок при смене CRM

Среда, 09 Августа 2017 г. 16:19 + в цитатник


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


Часто случается, что новую систему разрабатывают изначально неверно, что ошибки пропущены еще на этапе ТЗ. В результате, предприятие терпит неприятные потери, и чтобы не сойти с рельсов окончательно — возвращаются к старой CRM.

В этой статье мы разберем основные ошибки при уходе от Saas-решений к разработке на платформе, а также способы, с помощью которых эти ошибки можно не допускать вообще.



С чего начинаются проблемы


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



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

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



Если вовремя удастся обнаружить скрытую пружину — считайте, что вам повезло; обычно это сложно заметить, в то время как утечка денег компании при такой работе гораздо больше, чем просто ежемесячный тариф системы, которая при этом играет роль списка задач с карточками клиентов.

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



Что нанесет больший ущерб при уходе в новую систему


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




Как избежать этих расходов


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

Важно понимать, что этот вариант, опять же, — актуален не для всех. Есть куча примеров того, когда бизнес не растет: например, какая-нибудь группа элитных дизайнеров, которые выполняют дорогие заказы и работают по сарафанному радио для очень и очень толстых заказчиков. Они не хотят расти, им комфортно быть маленькими — так они готовы существовать годами.

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

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

Выходом из этих трудностей может стать правильный выбор платформы, определиться с чем действительно непросто.



На что смотреть, при выборе платформы


При выборе обращайте внимание на то, как сильно вы зависимы от разработчика. Если при использовании платформенного решения есть возможность для самостоятельной работы без каких-либо навыков программирования — то платформа «настоящая». То есть, важно то, насколько «отчуждаемая» сама платформа: вы взяли ее — и пошли работать; взяли документацию — и можно не обращаться к поставщику. Вообще.

Есть решения, в которых используются известные языки: SQL, VBS, JS. А есть те, кто изобретает «свой паскаль». Чем более известны встроенные скриптовые платформы и языки, — тем более вы независимы от вендора. К примеру, можно разрабатывать систему просто наняв любого студента программистского факультета. В паре с бизнес-аналитиком или человеком, который запросто ориентируется во всех ваших бизнес-процессах — обычный студент может спокойно выполнять работу разработчиков вендора, которые, как правило, берут за час своей работы весомые деньги (зависит от открытости системы).

Еще один очень важный момент — это прототипирование. Возможность накидать быстрый прототип системы для тестирования, — это действительно круто. С помощью такого инструмента вы проверите свои гипотезы и будете точно знать, как сформулировать ТЗ без ошибок.



Кратко рассмотрим нескольких вендоров:

Если вы берете, к примеру, «1С», — развивать систему вы сможете только силами сертифицированного программиста. Этот вариант подходит тем, кто не хочет рисковать качеством, и готов регулярно инвестировать средства в доработку системы и ее поддержку. Благо, что специалистов 1C на рынке огромное множество, поэтому настройка и обслуживание системы не может вызывать никаких проблем.

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

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



Как подготовиться к переходу на платформу


1 — Найти «идеолога»


С вашей стороны необходим человек, который может точно отразить текущие бизнес-процессы компании и формализовать их. Этот человек будет контролировать весь процесс разработки учитывая удобство пользователей, и постоянно сверяться с «картой» — направляя проект в нужную сторону.



2 — Создать прототип


Даже те компании, которые пережили неэффективные коробочные системы не всегда могут сформулировать те или иные задачи к новой системе. В этом лежат риски, связанные с тем, что при создании нового CRM-проекта можно заложить ошибки заранее, уже на уровне ТЗ. Поэтому, важным пунктом тут будет отлаживание — то есть вам надо не просто выстроить пробную модель, но и испытать ее на практике. Если визуальный редактор платформы позволяет накидать первую рабочую версию — обязательно воспользуйтесь такой возможностью и поиграйтесь с прототипом вместе в бизнес-аналитиком. Это сократит множество ошибок в разработке, которые вы могли допустить.



3 — Отделаться от вендора


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



4 — Подготовить сотрудников


Если бизнес вырос из системы — достаточно объяснить сотрудникам: «Ребята, мы выросли, давайте переходить на новую систему». При этом, используя платформу вы можете подготовить интерфейс системы таким образом, чтобы он был похож на старый — это снизит дискомфорт от перехода. Чем больше удобство пользователей — тем легче приживется система.



Заключение


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

Чтобы избежать основных потерь — нужно изначально внедрять платформу. Тут ключевой момент в том, чтобы это было с минимальным участием разработчиков. Да, конечно, можно использовать разработчика, это будет в какой-то степени удобно и здорово — но, снижение риска тут происходит в том случае, если вы можете развивать эту платформу самостоятельно, без каких-либо специальных знаний и разработчика — это ключ.

На рынке сейчас очень много платформ которые говорят: «Мы можем все, мы вам сделаем все, у нас платформа! То что нужно — мы вам все запрограммируем», однако истинная платформа — это только та система, которая может существовать, функционировать и развиваться силами клиента, дилера, — то есть без разработчика.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335262/


Метки:  

[Перевод] Увольнять, нанимать, повышать — культура вашей компании. Анатомия редиски

Среда, 09 Августа 2017 г. 16:00 + в цитатник
В первой части рассказа я утверждал, что основной причиной деградации культуры в компаниях является найм, удержание и продвижение «редисок» (наемных работников, чей недостаток эмпатии вызывает межличностные конфликты). В качестве системного решения этой проблемы я показал матрицу «Производительность-Ценности». Давайте посмотрим глубже и постараемся понять причины поведения редисок, и то, насколько крупные компании могут справится с ним без больших потерь.

Глава 1: Анатомия редиски («Темная триада»)


«Редиска» — это, конечно же, ненаучный термин, но люди используют его достаточно часто, так как он обладает единым культурным смыслом «ты точно поймешь, о чем это, когда сам увидишь». Моя цель — четко и в более понятном ключе классифицировать паттерн поведения, который вы, вероятно, распознаете интуитивно.

Если посмотреть на вопрос системно, то можно выделить три основных типа социально отталкивающих личностных черт, известных как «Темная триада»: психопатия, нарциссизм и макиавеллизм. Эти черты можно представить как трехмерную систему, которая в той или иной степени применима ко всем нам. Однако только те, у кого данные черты проявляются максимально интенсивно, могут подпадать под диагноз полномасштабного расстройства личности. Если вам любопытно, то можете пройти короткий тест, чтобы увидеть, насколько выражены у вас данные черты по сравнению с основной частью населения.

Ключ к пониманию Темной Триады заключается в том, что, хотя для всех трёх типов характерна бессердечность и склонность к манипулированию, делают они это по разным причинам. Психопаты руководствуются краткосрочными осязаемыми благами, и чтобы получить их, активно вовлекаются в опрометчивое, антисоциальное поведение. Макиавеллисты подпитываются долгосрочными осязаемыми благами, и выстраивают сложные стратегические схемы для достижения желаемого. Нарциссы мотивированы всем, что повышает их эго, независимо от того, является ли это осязаемым благом или простой похвалой, которая укрепляет их идеализированный образ.

Психопаты (а-ля Гордон Гекко)


Психопаты — также известные как «социопаты», или «антисоциальные личности», — это такие, типичные злодеи из кинофильмов. Их эмоции проецируют, в основном, бессердечность и агрессию, проявляющуюся в виде вспышек ярости или даже физического насилия с небольшой долей раскаяния. Их поведение, зачастую, импульсивное и безответственное; часто в явном виде игнорируют собственную и чужую безопасность. Они с восхищением бросают вызов нормам и законам, используют обман и манипуляции для получения прибыли или — что еще более жутко — для собственного развлечения.

image

Хотя только 1-2% населения подпадает под клинический диагноз «антисоциальное расстройство личности» (согласно руководству по психическим заболеваниям), такие люди, к сожалению слишком часто встречаются в корпорациях, особенно среди CEO. Яркими киновоплощениями психопатов были Гордон Гекко («Уолл-Стрит») и Патрик Бэйтмен («Американский психопат»).

Уникальным аспектом психопатов является то, что они концентрируются на краткосрочных целях: например, могут врать ради немедленного удовлетворения какого-то сиюминутного желания, даже если эта ложь может скомпрометировать их долгосрочные планы. Краткосрочные проявления безрассудства и поиск острых ощущения, как правило, ведут к амбициозному и безумному преступному поведению. Для любопытствующих я рекомендую книгу «Змеи в костюмах: когда психопаты идут на работу».

Макиавеллисты (а-ля Фрэнк Андервуд)


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

image

В отличие от психопатии, которая заложена генетически и редко исправима, макиавеллизм может быть более «изменяющимся состоянием», чем постоянной личностной чертой. Эксперимент Милгрэма, а также стэнфордский тюремный эксперимент позволили предположить, что обычно просоциальные люди могут вести себя удивительно по-макиавеллиански, когда оказываются в подходящей ситуации. Мне довелось видеть лидеров корпораций, которые кажутся абсолютно искренними в личной жизни, но при этом «включают» макиавеллизм, когда их компании встают перед сложными финансовыми дилеммами (например, набор и увольнение наемных работников). В частности, корпоративная культура Кремниевой долины поощряет такое поведение, восхваляя лидеров, которые «делают всё, что нужно», чтобы обеспечить выживание и успех своей компании.

Ирония заключается в том, что стартапы говорят, что любят «хасслеров» (англ. hassle) — пробивных и предприимчивых, то есть тех, кто добивается результата любой ценой, — хотя сам термин «хасслер» также описывает кого-то, кто всегда против и обманывает других. Совпадение? Возможно, нет. Любопытствующим советую прочесть классику: «Государь» Н. Макиавелли и «Искусство войны» Сунь Цзы. Из более современного интереса заслуживает работа Роберта Грина «48 законов власти».

Нарциссы (а-ля Тони Старк)


Большинство людей знакомы с наиболее очевидными проявлениями нарциссизма: грандиозная самоуверенность и эгоцентризм, которые выглядят как самодовольство и забота лишь о собственных интересах. Однако внутри себя нарцисс постоянно чувствует отсутствие безопасности и уверенности, отчего стремится к накачиванию своего эго, в конечном итоге прибегая и к самообману. Нарциссы очень сильно верят в чувство собственной значимости, даже когда можно проверить, что они явно преувеличивают собственную компетентность.

image

С точки зрения эмоций, нарциссы часто испытывают гнев и агрессию, если их хрупкому эго что-либо угрожает (этот симптом известен как «нарциссическая ярость»). Принимая во внимание то, что они не могут быть достаточно уязвимы и открыты для по-настоящему доверительного и интимного контакта, их отношения, как правило, неэмпатичны и искусственны. Они склонны к антагонистическому поведению по отношению к другим — манипулированию, лжи и угрозам, — а также к участию в различных действиях, часто безответственных, импульсивных и рискованных, позволяющих им казаться крутыми или смелыми.

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

По статистике, порядка 6% людей будут отвечать всем критериям нарциссического расстройства личности, при этом среди мужчин их больше (8%), чем среди женщин (5%). Так же, как и остальные представители Темной Триады, нарциссы широко представлены среди лидеров, особенно лидеров государств. Для более подробной оценки, а также психоаналитического взгляда на развитие нарциссизма, я советую прочесть книгу Алис Миллер «Драма одаренного ребенка и поиск собственного я».

Глава 2: Случайный редиска (высокофункциональный аутизм)


В отличие от Темных триад есть состояние, которое действительно может быть полезно для работы, оно называется «Расстройство аутистического спектра». Ранее оно носило название «синдрома Аспергера». Люди с расстройством аутистического спектра далеко не всегда являются редисками. Но за счет ослабленного чувства эмпатии они могут, на первый взгляд, казаться редисками.

Ключевое отличие в том, что Темные триады, в основном, малочувствительны к другим, в то время как люди с расстройством аутистического спектра могут быть полностью безразличны. У них есть трудности с подбором реплик, которые помогут им выглядеть социально приемлемо. Одной из лучших демонстраций этого отличия является фильм «Социальная сеть». Я не ставлю диагноз Марку Цукербергу (который является моим одногруппником по Гарварду и отличным парнем), я лишь хочу обсудить вымышленного персонажа фильма.

image

Фильм начинается с того, что Марк и Эрика идут на свидание, в результате которого Эрика бросает Марка, так как он наговорил ей ужасные вещи, которые она интерпретировала в качестве проявления его «редискиного поведения» (Темной триады). Однако в завершающей сцене фильма, Мэрилин (адвокат Марка) отмечает, что он, на самом деле, совсем не редиска, хотя, конечно, невнимателен к людям (расстройство аутистического спектра), что причиняет им боль, а просто пытается подражать жесткому поведению типичного CEO.

Первая сцена фильма [Эрика]: «Ты, наверное, будешь очень успешным человеком. И ты всю жизнь будешь думать, что девушки не любят тебя, потому что ты зубрила. Но я хочу, чтобы ты знал, говорю от чистого сердца: это точно не так. Они не любят тебя, потому что ты редиска»

Последняя сцена фильма [Мэрилин]: «Ты не редиска, Марк. Ты просто слишком сильно стараешься им быть.»

Когнитивная и эмоциональная эмпатия


Большинство людей считает, что эмпатия — это просто способность понимать других (или путают ее с симпатией). Но психологи разделяют два основных вида эмпатии: когнитивную и эмоциональную. Когнитивная эмпатия — это способность понимать психологическое состояние другого человека, в то время как эмоциональная эмпатия является способностью выдавать подходящую эмоцию в ответ на психологическое состояние другого человека.

Представьте, что вы увидели человека, который упал и порвал джинсы. С точки зрения когнитивной эмпатии вы поставите себя на его место и постараетесь понять, что он думает, скорее всего что-то вроде «Боже, как неловко!». Эмоциональная эмпатия в этой ситуации — это на самом деле испытать чувство стыда и неловкости за упавшего, а также чувство сострадательного желания помочь ему.

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

image

Неэмпатичные сообщники


Может показаться, что Темная Триада и люди с расстройством аутистического спектра не особо похожи на хорошо уживающихся друзей. Особенно принимая во внимание, что представители Темной Триады часто могут быть (поверхностно) очаровательны, в то время как люди с расстройством аутистического спектра зачастую имеют проблемы со встраиванием в общество. Но нередко такие люди становятся сообщниками, потому что дефицит эмпатии позволяет им дополнять друг друга в работе посредством странного паразитического симбиоза. Понять, как различается их мотивация в работе, можно на примере абстрактной сущности под названием «коробка»:

Люди с расстройством аутистического спектра сосредоточены на «создании лучшей коробки»: как она сконструирована, как ее можно улучшить, как ее можно использовать. Часто они хотят, чтобы другие люди слушали их объяснения про эту коробку и связанные с ней идеи, разделяли их энтузиазм, или хотя бы понимали или уважали их энтузиазм в отношении «коробки».

Представители Темной Триады сосредоточены на получении одобрения на «создание лучшей коробки» (независимо от того, сделали они ее или нет). Они хотят выглядеть как «строитель коробки», получить статус «Главного эксперта по созданию коробок», измышляют, как можно использовать эту коробку для зарабатывания денег, стараются скрыть факт, что кто-то еще делает коробку.


Мой любимый пример из кино на эту тему — байопик 2013 года «Джобс». В одной из сцен Стив Джобс убеждает своего друга Стива Возняка помочь ему с созданием новой видеоигры для Atari, но обманывает его, предлагая разделить гонорар в $700 (в реальности речь шла о $5000). Через много лет, читая книгу об истории Atari, Возняк узнал об обмане Джобса и был расстроен до слез. Таким образом, представители Темной Триады обычно выделяют людей с расстройством аутистического спектра, используют их как «приятелей», чтобы выжать максимум из их лояльности и таланта. А когда человек с расстройством аутистического спектра выясняет, что произошло, наши «герои» часто начинают давить и наезжать еще сильнее, чтобы обезопасить себя. Например, менеджер в своих интересах может влиять на аналитика, чтобы тот выдал многообещающие, но сомнительные данные, что впоследствии часто приводит к ссорам между ними (особо часто, когда ущерб уже необратим).

Глава 3: Управляя тьмой


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

В основном такие люди гораздо лучше работают на индивидуальных ролях. Принимая во внимание, что эмпатия является ключевым аспектом личности успешного менеджера, нужно понимать, что искренняя забота о сотрудниках напрямую влияет на их уровень удовлетворенности работой. Так что если представители Темной триады должны часто и активно взаимодействовать с другими, то они нуждаются в особом управлении, чтобы обеспечить их успех и благополучие окружающих. Использование матрицы «Производительность-Ценности», приведённой в первой главе, является ключом к усилению просоциального и устранения антисоциального поведения.

Важно понимать, что есть множество CEO с такими чертами, которые до сих пор всё еще дико успешны и восхваляемы всеми. Тот же Стив Джобс был невероятно талантливым визионером, окруженным талантливой командой. Нахождение в окружении операционных лидеров с высоким эмоциональным интеллектом может быть полезно для сохранения баланса между высоким IQ и темпераментом CEO, чтобы помогать компании неуклонно двигаться вперед.

Если вы хотите использовать успешную историю основателя Apple в качестве извинения за выставление напоказ ваших темных черт, просто помните: вы не Стив Джобс. В отличие от этого «принца эпохи ренессанса», как CEO вам лучше быть любимым сотрудниками, чем вселять страх. Эффективные лидеры должны воплощать свет, понимая и управляя темными чертами своих сотрудников.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334870/


Метки:  

Мультипротокольный NAS-доступ к Netapp-ресурсам c ACLs

Среда, 09 Августа 2017 г. 15:18 + в цитатник
imageНебольшое предисловие к статье. Заказчик выставил требование организовать доступ по CIFS (SMB) к некоторым NFS-экспортам, которые лежат на NetApp. Звучит вроде бы несложно: нужно создать CIFS-шару на уже экспортированном qtree. Позже было выставлено требование, что нужно гранулярно управлять доступом на эти шары. Опять-таки задача выглядит решаемой: это можно контролировать и с NetApp и через оснастку Shared Folders (share permissions). Затем выяснилось, что нужно варьировать доступ к различным подпапкам на CIFS-шаре. Это уже оказалось нетривиальной задачей. Так как нужно было настроить списки контроля доступа (ACL) и для CIFS и для NFS к одним и тем же данным.

На первый взгляд, можно воспользоваться классическими правами доступа в Linux. У каждой папки и файла есть атрибуты владельца, группы владельца и others (все остальные). Ниже приведен пример классических прав доступа в Linux.
image

Но что делать, если нужно более гранулярно контролировать доступ? POSIX ACLs? Они не поддерживаются NetApp. В итоге единственным решением оказались NFSv4 ACLs.

В этой статье предлагаем описание того, как транслировать NFSv4 ACLs для Windows-пользователей. Будем проводить нашу настройку пошагово. Стиль будет максимально сжатый и емкий. Я не буду останавливаться на каждом пункте подробно, к тому же не буду приводить детального листинга всех команд. Итак, приступим.

Привязка NetApp к LDAP


Предполагается, что в данной инфраструктуре существует сервер LDAP, через который происходит авторизация и аутентификация пользователей. Поэтому маппинг не используется и соответственно файл usermap.cfg не правится. Также не нужно вносить изменений в файлы passwd и group — все пользователи и группы берутся из LDAP. Ниже приведены параметры необходимые для нормальной работы сцепки:

image

Их необходимо выполнить на целевом vFiler. Отмечу, что существуют различные вариации этих настроек. И в вашей конкретной инфраструктуре это может не взлететь. В нашем случае мы цеплялись к AD DC с FSMO ролью Global Catalog. Проверка работоспособности сцепки на NetApp возможно провести командами getXXbyYY и wcc. Эти команды можно выполнить только в advanced mode.

Примеры корректной работы команды getXXbyYY:
image

Если эта команда не возвращает подобный вывод, значит что-то настроено не так.

Для того, чтобы корректно работало разрешение имен и групп, в Unix-средах нужно сделать правки в файле /etc/nsswitch.conf. Выставляем в начало ldap для строк passwd и group:
passwd: ldap nis files
group: ldap nis files

Есть небольшая ремарка относительно корректной работы групп в случае использования LDAP. Внутри групп, которые будут иметь доступ к Linux и Windows средам одновременно, должен быть заполнен атрибут ‘memberUid’. Важно: он должен быть заполнен в нижнем регистре. В атрибут необходимо прописать пользователей этой группы. Ниже выделено поле memberuid в атрибутах группы, которая должна быть доступна в средах Linux и Windows.

image

Конфигурация NFSv4 на NetApp.


Мы хотим транслировать NFSv4 permissions (читай UNIX) в Windows среду, то есть они будут основными списками контроля доступа. Поэтому мы будем использовать для наших томов/qtree UNIX-style permissions.

Создаем том/qtree, создаем на нем экспорт NFS. В файле /etc/exports видим следующую картину:

/vol/xxx_VFILER03_nfs_vol00/ACL_test -sec=sys,rw,root=192.168.0.1,nosuid

Делаем настройку следующих опций:
image

Конфигурация NFSv4 ACLs на Linux


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

Монтируем экспорт со следующими опциями:
nfs acl,defaults,intr,hard,bg,tcp,auto,rw 0 0

Затем уже внутри нашего экспорта назначаем ACLы согласно нашим потребностям. NFSv4 ACLs чуть помощнее чем POSIX ACLs и довольно близки к CIFS ACLs. Существует 2 команды для работы со списками: nfs4_getfacl и nfs4_setfacl. Нетрудно догадаться, что одной командой мы считываем имеющиеся списки доступа, а второй назначаем. Ниже пример настройки NFSv4 ACLS на папку test:
image
Где А – allow, D – deny.

При внесении изменений воспользуемся командой:
image
Тогда конфиг откроется в текстовом редакторе.

Как мы видим существует множество возможностей контролировать доступ для каждого файла и папки.

Теперь необходимо настроить доступы. После этого проверяем, что на Linux нужные права для нужных пользователей.

Создание CIFS шары на NetApp


Для этого настраиваем сервисы CIFS через cifs setup.
После этого создаем CIFS шару на файлере на тот же том/qtree, на котором у нас лежит экспорт.
image
Права при создании шары оставляем EVERYONE/FULL CONTROL. Это нужно для того, чтобы не было лишних ограничений на уровне шары.
image
Права на уровне файловой системы уже регулируются при помощи инструмента NFSv4 ACLs.

Это было финальной настройкой. Теперь подключаемся теми же юзерами, которыми подключались в Linux, и проверяем доступ. У NetApp есть старая утилита, которая показывает Linux permissions в средах Windows. Называется она SecureShare. Можно также воспользоваться для проверки и ею. Ниже скриншот дополнительной вкладки после установки утилиты SecureShare.

image
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335256/


Метки:  

Взгляд снизу вверх или Ubuntu Server для разработчика электроники. Часть 2

Среда, 09 Августа 2017 г. 15:11 + в цитатник
Продолжаем развивать тему использования компьютера с ubuntu server в качестве устройства для связи мира микроконтроллеров с миром персональных компьютеров
Ссылка на часть 1.
image
Напомню, что статья описывает практику применения описанной техники и не ставит целью охватить все глубины и возможности современной аппаратуры. Это один из вариантов решения поставленной задачи.

В этой части я покажу, как проходить следующие моменты:
  • Статический IP + DHCP сервер
    В локальной сети на данный момент предполагается всего два устройства. Сам сервер и управляющая машина. Исходя из данной простоты настроим Ubuntu server.
    Статический IP
    Опорная информация
    1. Чтобы узнать логическое имя (logical name) сетевого интерфейса делаем:
    sudo lshw -C network
    и ищем строчку
     logical name: enp3s0

    Вариант использования функции ifconfig (как аналог ipconfig в windows) иногда может дать только loop 127.0.0.1. Название интерфейса зависит от аппаратуры. На двух разных машинах ставил ubuntu с одной флэшки и были разные имена сетевых интерфейсов. enp3s0 — это классификация по шине и номеру устройства, как я понимаю. Бывают ещё из такой серии eth0 и такой ens35. Не пугайтесь.

    2. Изменение файла конфигурации сети
    sudo nano /etc/network/interfaces
    (nano — эта маленький текстовый редактор)
    Должно быть так:
    	# This file describes the network interfaces available on your system
    	# and how to activate them. For more information, see interfaces(5).
    
    	source /etc/network/interfaces.d/*
    
    	# The loopback network interface
    	auto lo
    	iface lo inet loopback
    
    	# My local network.
    	allow-hotplug enp3s0
    	iface enp3s0 inet static
    	address 172.16.55.1
    	netmask 255.255.255.0
    	gateway 172.16.55.1
    

    Нажимаем cntrl-x — для выхода из редактора
    Нажимаем y — для сохранения изменений

    3. Перезагружаем сетевой сервис:
    service networking restart


    DHCP сервер
    Опорная информация
    1. Редактируем файлы для работы DHCP сервера
    sudo nano /etc/default/isc-dhcp-server
    найдите строчку
    INTERFACES=""
    — это название интерфейса для DHCP сервера. В нашем случае должно быть так:
    INTERFACES="enp3s0"

    В файле
    sudo nano /etc/dhcp/dhcpd.conf
    нужно добавить
    subnet 172.16.55.0 netmask 255.255.255.0{
     range 172.16.55.2 172.16.55.100;
    }
    В рамках этой подсети DHCP сервер будет выдавать адреса в диапазоне от 2 до 100.

    2. Если будете использовать функцию gethostbyname(), то в файле
    sudo nano /etc/hosts
    должно быть прописано имя пк и IP. Возможно есть более удобный способ получить свой собственный IP, но мне он не поддался.
    127.0.0.1	localhost
    172.16.55.1	ubuntu

    В файле /etc/hostname хранится имя пк (ubuntu). Можно посмотреть через
    sudo cat /etc/hostname
    и ещё миллионом способов.

    3. Перезагружаем сетевой сервис:
    service networking restart

    SSH доступ
    По идее, подключив теперь стационарный компьютер, мы получи для него IP и сможем иметь доступ по SSH. Для доступа из Windows я использовал утилиту PuTTY. Там же, в программных файлах PuTTY, есть утилита для передачи данных по сети.
    Вот состав батника для передачи файлов с Ubuntu на Windows.
    d:\"Program Files"\PuTTY\pscp.exe ubuntu@172.16.55.1:/home/ubuntu/tool/* "F:/WORK/SERVER/tool/"

    И для закачки на сервер
    d:\"Program Files"\PuTTY\pscp.exe "F:/WORK/SERVER/tool/*" ubuntu@172.16.55.1:/home/ubuntu/tool/

  • Ставим драйвер от FTDI
    Драйвера от FTDI поставляются в сжатом виде. Содержатся в пакете сами драйвера, библиотеки, примеры использования и README.pdf файл, который больше всего был интересен. Из файла D3XX Programmers Guide ни разу не ясно, как использовать драйвер для Linux. Пришлось даже написать в тех поддержку FTDI, благо они своевременно и по делу отвечают. Можно было бы и не писать, если бы я сразу раскрыл этот архив. Но полезными оказались ссылки, которые они прислали, примеры разводки и схемотехники.
    Как показано выше, с помощью утилиты pscp из комплекта PuTTY, копируем на сервер драйвер. У меня был d3xx-linux-i686-0.5.0.tar.bz2. Заходим в эту папку на сервере и делаем
    tar -xvf d3xx-linux-i686-0.5.0.tar.bz2

    Далее, по инструкции FTDI исполняем:
    cd linux-i686
    sudo rm -f /usr/lib/libftd3xx.so
    sudo cp -f libftd3xx.so /usr/lib
    sudo cp -f libftd3xx.so.0.5.0 /usr/lib
    sudo cp -f 51-ftd3xx.rules /etc/udev/rules.d
    sudo udevadm control --reload-rules
    

  • Компилируем программу
    Программу я писал в codeBlocks и она, за исключением некоторых моментов, в том числе и из-за FTDI, совместима с Windows. Перестала она компилироваться для Windows, когда я поставил туда h файл из драйвера для linux D3XX (c D2XX и FT232RL чипом не было проблем).
    Теперь makefile. Программисты и так знают зачем он нужен, просто укажу особенности:
    STATLIB=libftd3xx.a — указываем название библиотеки для Linux
    CFLAGS=$(DEPENDENCIES) -Wall -Wextra -std=c++11 — разрешаем c++11
    пример makefile для одного файла проекта main.cpp
    CC=g++
    UNAME := $(shell uname)
    ifeq ($(UNAME), Darwin)
    	DEPENDENCIES := -lpthread -ldl -lobjc -framework IOKit -framework CoreFoundation
    else
    	DEPENDENCIES := -lpthread -ldl -lrt
    endif
    CFLAGS=$(DEPENDENCIES) -Wall -Wextra -std=c++11
    STATLIB=libftd3xx.a
    APP = prgr
    
    all: $(APP)
    
    $(APP): main.o 
    	$(CC) -o $(APP) main.o $(STATLIB) $(CFLAGS)
    
    main.o: main.cpp
    	$(CC) -c -o main.o main.cpp $(CFLAGS)
    
    clean:
    	rm -f *.o ; rm $(APP)
    

    Таким образом, в папке проекта лежат файлы main.c ftd3xx.h makefile libftd3xx.a и прочие файлы проекта. И для компиляции проекта теперь нужно зайти в эту папку и сделать
    make

  • daemon
    Роль демонов в Linux похожа на роль служб в Windows. Это программы, которые живут в фоновом режиме и делают всякую периферическую работу. Всё начинается с systemd — программы, которая запускается первой, имеет соответственно PID=1, и запускает все другие фоновые задачи через скрипты. Поковырявшись в Ubuntu, я удивился насколько много всего внутри построено на скриптах. Вы уже видели, как меняется статический IP, настраиваются программы, простой коррекцией файлов в текстовом редакторе.
    Выполнив
    ps -el
    Вы увидите список запущенных программ с их PID. PID — это обязательный идентификатор запущенной программы, по которому за этой программой следит ОС. В крайней ситуации, можно грохнуть программу по этому PID из терминала — пишите kill и PID (может пригодиться для отладки).
    Так вот, при запуске демона исполняется скрипт, в котором указано когда и как программу нужно запустить, как её остановить или перезапустить. Чтобы демон работал нормально, программа при запуске должна сохранить в файл, путь к которому указан в скрипте, свой PID и перейти в другой поток (в фоновый режим).
    Пособие по демону меня ввело в грусть и тоску. Сильно упростив демона, я его превратил в утилиту для запуска любой программы. Но обязательная часть не поменялась. Помимо этого, он ведет лог, чтобы проверить, если вдруг что.
    код daemon
    void SetPidFile(char* Filename)
    {
        FILE* f;
        f = fopen(Filename, "w+");
        if (f)
        {
            fprintf(f, "%u", getpid());
            fclose(f);
        }
    }
    
    
    int main( int argc, char** argv )
    {
        char toolfile[32];
        char folder[32];
        intptr_t ret;
        FILE* logfile;
    
        if( argc!=3 )
        {
            printf( "Write address of the program and name: /home/ubuntu/tool/ tool\n");
            return -1;
        }
        pid_t pid, sid;
    
        pid = fork();
        if (pid < 0)
        {
            sleep(1);
            return -1;
        }
        //We got a good pid, Close the Parent Process
        if (pid > 0) {
            return 0;
        }
        //Create a new Signature Id for our child
        sid = setsid();
        if (sid < 0)
        {
            return -1;
        }
        //Change File Mask
        umask(0);
        //Save PID
    
        memcpy( toolfile, argv[0], strlen(argv[0]) );
        memcpy( toolfile + strlen(argv[0]), ".log", 4 );
        memset( toolfile + strlen(argv[0]) + 4, 0, 1 );
        printf( "Daemon:: log to:%s\n", toolfile );
        logfile = fopen( toolfile, "w" );
    
        fprintf( logfile, "Daemon:: started with 0=%s 1=%s 2=%s\n", argv[0], argv[1], argv[2] );
    
        memset( toolfile, 0, 32 );
        memcpy( toolfile, argv[0], strlen(argv[0]) );
        memcpy( toolfile + strlen(argv[0]), ".pid", 4 );
        memset( toolfile + strlen(argv[0]) + 4, 0, 1 );
        SetPidFile( toolfile );
        fprintf( logfile, "Daemon:: PID=%u saved in the %s\n", getpid(), toolfile );
    
        memset( folder, 0, 32 );
        memcpy( folder, argv[1], strlen(argv[1]) );
        fflush ( logfile );
    
        memset( toolfile, 0, 32 );
        memcpy( toolfile, folder, strlen(argv[1]) );
        memset( toolfile + strlen(argv[1]), '/', 1 );
        memcpy( toolfile + strlen(argv[1]) + 1, argv[2], strlen(argv[2]) );
    
        //Change Directory
        //If we cant find the directory we exit with failure.
        if ((chdir(folder)) < 0)
        {
            fprintf( logfile, "Daemon:: Program folder was not found:%s\n", folder );
            fclose( logfile );
            return -1;
        }
    
        //Close Standard File Descriptors
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
    
        fprintf( logfile, "Daemon:: Program started\n" );
        fflush ( logfile );
        ret = execl( toolfile, folder, NULL );
        if( ret==-1 )
        {
            fprintf( logfile, "Daemon:: execl error: %s. File=%s Folder=%s\n", strerror(errno), toolfile, folder );
            fclose( logfile );
            return -1;
        }
    
        fprintf( logfile, "Daemon:: closed\n" );
        fclose( logfile );
        return 0;
    }
    

    Компилируем демона.

    На данный момент в нашем рабочем каталоге, допустим /home/ubuntu/daemon/, имеем:
    daemon — программа демона
    prgr — программа
    prgr.strt — скрипт, который нужно выполнить до запуска программы (если надо)
    prgr.stop — скрипт, который нужно выполнить для остановки программы (если надо)

    Нужно разрешить программам работать:
    sudo chmod 755 ./tool
    sudo chmod 755 ./daemon


    Теперь нужен скрипт для systemd
    Делаем
    sudo nano /etc/systemd/system/mydaemon.service
    и записываем туда наш скрипт.
    mydaemon.service
    [Unit]
    Description=my service
    After=network.target
    After=isc-dhcp-server.service
    
    [Service]
    Type=forking
    PIDFile=/home/ubuntu/daemon/daemon.pid
    ExecStartPre=/bin/sh /home/ubuntu/daemon/prgr.strt
    ExecStart=/home/ubuntu/daemon/daemon /home/ubuntu/daemon/prgr prgr
    ExecStop=/bin/sh /home/ubuntu/daemon/prgr.stop
    Restart=always
    TimeoutSec=5
    
    [Install]
    WantedBy=multi-user.target
    

    В скрипте кратко:
    Description — краткое название-описание
    After — что требуется для запуска
    Type=forking — systemd предполагает, что служба запускается однократно и процесс разветвляется с завершением родительского процесса.
    PIDFile — файл с PID программы из демона
    ExecStartPre — до запуска программы
    ExecStart — программа с параметрами
    ExecStop — как остановить
    WantedBy — уровень, на котором запускать

    Теперь можно попробовать всё запустить.
    Пишем
    systemctl daemon-reload
    systemctl status mydaemon

    Если всё без ошибок, то запускаем:
    systemctl start mydaemon

    После этого смотрите лог демона, всё должно поехать.
    Чтобы работала автозагрузка
    systemctl enable mydaemon


Друзья, жду Ваших интересных комментариев и ценных советов. Если где соврал — сильно не гневайтесь, просто указывайте, что можно сделать лучше. Надеюсь, появится 3 часть про большой скрипт, автоустановку… может ещё что.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335042/


Метки:  

[Из песочницы] Социальная сеть для киноманов или как не закопаться, разрабатывая еще одну соцсеть

Среда, 09 Августа 2017 г. 14:58 + в цитатник

Редизайн или немного больше?


Осенью 2016 года ко мне по рекомендации обратился заказчик с просьбой разработать iOS приложение для киноманов с достаточно обширным функционалом. На тот момент уже существовал готовый прототип с, мягко говоря, примитивным UI. Задача стояла следующим образом: сделать редизайн с доработкой “кое-какого” функционала. Уже тогда у меня закралась идея, что редизайном дело не обойдется, но на сколько объемный это проект я не осознавал. Но тем интереснее…


Приступив к работе, я начал поиск подходящих решений для UI. Конечно же, сначала был проведен обширный ресерча существующих приложений на рынке. Были пересмотрены десятки рекомендательных сервисов о кино, начиная от всем известных IMDb и Rotten Tomatoes и заканчивая новыми сервисами, которые в маркете появились совсем недавно.

Социальная сеть или рекомендательный сервис?


Итогом процесса ресерча стало два варианта UI, которые значительно разнились между собой как внешне, так и по смысловому предназначению.

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

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

В этот момент стал вопрос “какое основное предназначение приложения: рекомендательный сервис или же полноценная социальная сеть для киноманов?”. Решение было принято в пользу социальной сети. В этот момент я однозначно понял, что ввязался в нешуточную историю. Но почему-то меня это не остановило, а наоборот подзадорило. Такую задачу я еще не решал.

Flow


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


C учетом ориентира на социальную сеть, была доработана вторая версия UI. В пользу еще большего акцента на контент приложения, было принято решение отказаться от большинства цветов. Остался только акцентный синий цвет, похожий на системный цвет операционной системы Windows и несколько оттенков серого для текстов. В качестве основного шрифта остановились на универсальном общедоступном Open Suns, а для заголовков я выбрал один из моих любимых шрифтов Montserrat.


Я приступил к разработке интерфейса с одного из главных экранов – movie page.

Данный screen содержит полную информацию о фильме.

Перечень элементов Movie Page:


  • название,
  • продолжительность,
  • дата релиза,
  • жанры,
  • описание,
  • режиссер,
  • актеры

А также на movie page выводятся рейтинги авторитетных ресурсов о кино:

  • IMDB
  • Rotten Tomatoes
  • Raters Friends – рейтинг друзей, собственный рейтинг приложения, который формируется по формуле среднего арифметического рейтинга исключительно друзей пользователя. Данный рейтинг собственно является одним из главных УТП (уникальное торговое предложение) приложения.

Кроме этого на movie page должны присутствовать основные управляющие элементы – кнопки Rate и To Watch List. С помощью первой выставляется рейтинг фильм, вторая кнопка добавляет фильм в To watch list. Оба действия взаимоисключающие, а это значит, что после нажатия одной из них, вторая кнопка должна стать недоступной.

Разместить такое количество информации на одном экране, да так, чтобы не загромоздить его, задача не из простых. Вот какое решение появилось в итоге:

Далее последовали остальные экраны, такие как Timeline, Raters Friends, Comment page, все экраны Login/Registration, экраны имеющие отношение к Profile и еще несколько десятков скринов.

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

Структурная сетка приложения получилась достаточно сложной. Каждый экран имеет разные элементы, поэтому общими оставались отступы от края, размеры header и menu и некоторые отсупы между элементами, по типу афиш фильмов.


Иконографика


Главное управляющее меню имеет простые понятные иконки, нажатием на которые осуществляется навигация между основными экранами:

  1. Timeline
  2. Search
  3. Notification
  4. Profile

Более объемные иллюстрации были созданы преимущественно для Landing Page, но также используются в Onboarding.



Иконка


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


Зачем приложению сайт?


После детальной проработки всех элементов интерфейса и всех лейаутов настало время для разработки Landing Page. Я считаю, что любое уважающее себя приложение обязано иметь посадочную страницу. Raters App не стал исключением. Во время разработки приложения основная задача лендинга заключалась в сборе эмейлов, для оповещения о релизе приложения. После релиза лендинг должен перенаправлять трафик на маркетплейсы: AppStore и GooglePlay. Но при этом сайт должен подробно рассказать об основных фичах приложения.


Приблизительно таким образом рекомендательный сервис перерос в социальную сеть. Конечно, данный проект никогда не будет полностью завершен, он как и любая „социалка“ должен итеративно обновляться и развиваться в ногу со временем. Уже на данный момент расписан график нескольких апдейтов. Но чтобы это произошло, Raters App нужны базовые пользователи, а как их получить уже совсем другая история.

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335252/


Расширение, изменение и создание элементов управления на платформе UWP. Часть 3

Среда, 09 Августа 2017 г. 14:53 + в цитатник


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

Часть 3. Создание новых элементов управления



По средством присоединенных свойств (Attached Properties) и поведений (Behaviors) мы имеем возможность расширять существующие элементы управления без вмешательства в их внутренее устройство. Располагая же разметкой их шаблонов, мы также можем изменить их внешний вид и работу визуальных состояний (VisualState). Однако, если требуется изменить или расширить логику существующего элемента управления, или и вовсе создать новый элемент управления, то нам необходимо опуститься на уровень кода (ControlName.cs).


Создание нового элемента управления на базе существующего

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

Расширим его следующим образом:
  1. Функционалом валадиции по заданому шаблону Regex
  2. Визуальным индикатором сообщающим статус валидации
  3. Визуальным индикатором сообщающим является ли поле ввода обязательным к заполнению

В результате получим следующий элемент управления


Элемент управления ExtendedTextBox

Итак, приступим.
Создадим новый элемент управления. Для удобства предлагается размещать их в проекте по следуещему пути “.../Controls/ControlName/ControlName.cs”.


Размещение нового элемента управления в проекте

Добавляем новый элемент проекта как Templated Control. Не смотря на то, что данный шаблон не особо сильно отличается от нового пустого класса, главное, что он автоматически создает пустую заглушку шаблона разметки в файле Generiс.xaml для нового элемента управления. А в случае отсутствия данного файла создает его. Именно в этом файле по умолчанию осуществляется поиск шаблона разметки пользовательских элементов управления.


Создание нового элемента проекта по шаблону Templated Control


    


Шаблон разметки нового элемента управления по умолчанию

При этом namespace у всех новых элементов управления рекомендуется указывать общий, для упрощения работы с ними из XAML. А также изменить базовый класс на тот который мы собираемся взять за основу. В данном случае TextBox.

После чего внести некоторые правки в шаблон разметки по умолчанию.


Изменение namespace и базового класса


    


Исправленный шаблон разметки элемента управления

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


    
        
    

Использование нового элемента управления


Внешний вид нового элемента управления

Следующим шагом является переиспользование шаблона разметки элемента управления TextBox (об этом мы подробно писали в предыдущей части).
Получив его, заменяем им шаблон нового элемента управления ExtendedTextBox. Не забываем поменять в нужных местах значения атрибутов TargetType c TextBox на ExtendedTextBox.


Исправленная разметка нового элемента управления

Теперь элемент управления ExtendedTextBox является точной копией элемента управления TeBox, повторяя как его внешний вид, так и функционал.


Новый элемент управления повторяет внешний вид TextBox

Приступим к расширению функционала.

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

Находим в шаблоне разметки часть ответствунную за Header и изменяем её следующим образом:


    
    


Внедрение в разметку индикатора “*”

Параллельно с этим в файле ExtendedTextBox.cs вносим следующие изменения

public sealed class ExtendedTextBox : TextBox
{
    private TextBlock _necessityIndicatorTextBlock;

    public ExtendedTextBox()
    {
        this.DefaultStyleKey = typeof(ExtendedTextBox);
    }

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        _necessityIndicatorTextBlock = GetTemplateChild("NecessityIndicatorTextBlock") as TextBlock;

        UpdateControl();
    }

    public bool IsNecessarily
        {
            get => (bool)GetValue(IsNecessarilyProperty);
            set => SetValue(IsNecessarilyProperty, value);
        }

    public static readonly DependencyProperty IsNecessarilyProperty =
        DependencyProperty.Register("IsNecessarily", typeof(bool), typeof(ExtendedTextBox), new PropertyMetadata(false, IsNecessarilyPropertyChanged));

    private static void IsNecessarilyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textbox = d as ExtendedTextBox;
        if (textbox == null || !(e.NewValue is bool))
        {
            return;
        }

        textbox.UpdateNecessityIndicator();
    }

    private void UpdateControl()
    {
        UpdateNecessityIndicator();
    }

    private void UpdateNecessityIndicator()
    {
        if (_necessityIndicatorTextBlock != null)
        {
            _necessityIndicatorTextBlock.Visibility = IsNecessarily ? Visibility.Visible : Visibility.Collapsed;
        }
    }
}

Состояние класса ExtendedTextBox

Здесь обратим внимание на следующее:
  • Переопределяем метод OnApplyTemplate() и находим ссылки на элементы разметки по заданным x:Name для дальнейшей работы с ними
  • Определяем свойство зависимости IsNecessarily, определяющее является ли данное поле ввода обязательным к заполнению, и его PropertyChangedCallback IsNecessarilyPropertyChanged в теле которого обновляем видимость данного индикатора.


Важно. Стоит обратить внимание на то, что при инициализации элемента управления PropertyChangedCallback-функции могут выполняться раньше, чем вызовется метод OnApplyTemplate(). Из-за чего мы получаем ситуацию, когда в момент выполнения данных функций дерево элемента ещё не загруженно и целевые объекты не найдены. По этой причине необходимо в конце метода OnApplyTemplate() привести состояние элемента управления в корректное. Здесь это выполняет метод UpdateControl().
Теперь если задать значение свойства IsNecessarily как true мы получим следующий результат.


Индикатор обязательности ExtendedTextBox

2. Займемся логикой валидации введенных данных по заданому шаблону Regex.

Определим следующее:
  • Свойство зависимости RegexPattern и его CallBack-функцию RegexPatternPropertyChanged
  • Свойство зависимости IsValid c приватным set-аксессором.
  • Метод ValidateTextBox() вызываемый при изменении свойств RegexPattern или Text.

И внесем ещё несколько изменений в код класса в результате чего он станет выглядеть следующим образом

public sealed class ExtendedTextBox : TextBox
{
    private TextBlock _necessityIndicatorTextBlock;

    public ExtendedTextBox() ...

    protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.TextChanged -= ExtendedTextBoxTextChanged;
            _necessityIndicatorTextBlock = GetTemplateChild("NecessityIndicatorTextBlock") as TextBlock;
            this.TextChanged += ExtendedTextBoxTextChanged;
            UpdateControl();
        }

    private void ExtendedTextBoxTextChanged(object sender, TextChangedEventArgs e)
    {
        ValidateTextBox();
    }

    //public bool IsNecessarily ...
    //public static readonly DependencyProperty IsNecessarilyProperty = ...
    //private static void IsNecessarilyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) ...

    public string RegexPattern
        {
            get { return (string)GetValue(RegexPatternProperty); }
            set { SetValue(RegexPatternProperty, value); }
        }

    public static readonly DependencyProperty RegexPatternProperty =
        DependencyProperty.Register("RegexPattern", typeof(string), typeof(ExtendedTextBox), new PropertyMetadata(string.Empty, RegexPatternPropertyChanged));

    private static void RegexPatternPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textbox = d as ExtendedTextBox;
        if (textbox == null || !(e.NewValue is string))
        {
            return;
        }

        textbox.ValidateTextBox();
    }

    private void ValidateTextBox()
    {
        IsValid = Regex.IsMatch(Text, RegexPattern);

        if (this.Text.Length == 0 || !this.IsValid.HasValue)
        {
            VisualStateManager.GoToState(this, "Indeterminate", true);
            return;
        }

        VisualStateManager.GoToState(this, this.IsValid.Value ? "Valid" : "Invalid", true);
    }

    public bool? IsValid
        {
            get { return (bool?)GetValue(IsValidProperty); }
            private set { SetValue(IsValidProperty, value); }
        }

    public static readonly DependencyProperty IsValidProperty =
        DependencyProperty.Register("IsValid", typeof(bool?), typeof(ExtendedTextBox), new PropertyMetadata(default(bool?)));

    private void UpdateControl()
    {
        UpdateNecessityIndicator();
        ValidateTextBox();
    }

    //private void UpdateNecessityIndicator() ...
}

Состояние класса ExtendedTextBox после добавления логики валидации

Важно. Ввиду того, что изменение шаблона элемента управления возможно во время исполнения необходимо с осторожностью подходить к подпискам на события в методе OnApplyTemplate(). Так, одной из практик устранения лишних прослушиваний изменений свойств при изменении шаблонов является отписка от событий с последующей переподпиской в теле данного метода.
Также обратим внимание на тело метода ValidateTextBox() который в зависимости от состояния валидности вызывает метод класса VisualStateManager переводящий визуальное состояние элемента управления в одно из трех состояний на которые мы ссылаемся, но ещё не определили в разметке шаблона.

Первым делом несколько расширим разметку строения элемента управления


    
        
        
        
        
    
    
        
        
    
    
    
    
        
        
    
    
    
    
    


Расширение Grid и добавление картинки-индикатора валидности

И добавим нужные визуальные состояния с описанием их логики.

    
    
        
            
                
            
        
    
    
        
            
                
            
        
    


Новая визуальная группа ValidStates

Теперь мы можем создать следующую страницу ввода данных


Страница ввода данных

В заключение данного примера обратим внимание, что объем кода в файла ExtendedTextBox.cs хоть и не очень большой, но в перспективе, в случае дальнешего расширения логики элемента управления, может доставлять определенные неудобства в ориентации по файлу.
Чтобы свести такие неудоства к минимуму предлагаем воспользоваться частичными (partial) классами и создать по собственному усмотрению дополнительные файлы с декларациями строения класса.

Например, следующим образом:


Строение проекта при разделении деклараций элементов управления на частичные


Вид файлов содержащих частичные декларации элемента управления

На этом закончим работу с данным элементом управления. Аналогичным образом мы можем расширять логику, внешний вид, добавить дополнительные свойства зависимости для лучшей параметризации (например, свойствами ValidImageSource и InvalidImageSource)

Создание нового элемента управления

В данном пункте мы рассмотрим процесс создания нового элемента управления с нуля. Принципиально этот процесс ничем не отличается от того, что мы делали в предыдущем пункте.
В качестве примера рассмотрим полезный но не вошедший в поставку UWP элемент управления Expander.

public partial class Expander
{
    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register(nameof(Header), typeof(string), typeof(Expander), new PropertyMetadata(null));

    public static readonly DependencyProperty IsExpandedProperty =
        DependencyProperty.Register(nameof(IsExpanded), typeof(bool), typeof(Expander), new PropertyMetadata(false, OnIsExpandedPropertyChanged));

    public string Header
    {
        get { return (string)GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }

    public bool IsExpanded
    {
        get { return (bool)GetValue(IsExpandedProperty); }
        set { SetValue(IsExpandedProperty, value); }
    }
}

Свойства зависимости элемента управления Expander

public sealed partial class Expander : ContentControl
{
    public Expander()
    {
        this.DefaultStyleKey = typeof(Expander);
    }

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        if (IsExpanded)
        {
            VisualStateManager.GoToState(this, "Expanded", true);
        }
    }

    private void ExpandControl()
    {
        VisualStateManager.GoToState(this, "Expanded", true);
    }

    private void CollapseControl()
    {
        VisualStateManager.GoToState(this, "Collapsed", true);
    }

    private static void OnIsExpandedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var expander = d as Expander;

        bool isExpanded = (bool)e.NewValue;
        if (isExpanded)
        {
            expander.ExpandControl();
        }
        else
        {
            expander.CollapseControl();
        }
    }
}

Основная часть элемента управления Expander

Здесь обратим внимание на то, что у Expander предполагается наличие контента который может быть чем угодно. Ввиду этого имеет смысл наследовать его не от класса Control а от расширяющего его класса ContentControl чтобы сразу получить функционал работы со свойством Content.



Шаблон разметки элемента управления Expander

Интересным местом в данной разметке является свойство IsChecked элемента управления ToggleButton а именно то, каким образом мы его привязываем к свойству IsExpanded родительского элемента. Такой способ привязки обусловлен тем, что TemplateBinding не предоставляет свойство Mode которое будучи установленным в значение TwoWay должно влиять на состояние Expander.

В данных статьях мы подробно рассмотрели средства расширения, изменения и создания элементов управления на платформе UWP. Надеемся, что материалы показались вам интересными и полезными.

В следующих статьях мы рассмотрим вопросы оптимизации процесса разработки на UWP.

Если что-то было по вашему мнению освещено недостаточно подробно — с удовольствием ответим на все вопросы в комментариях!

Ян Мороз, старший .NET разработчик
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335240/


Метки:  

Двухфакторная аутентификация в Check Point Security Gateway

Среда, 09 Августа 2017 г. 14:46 + в цитатник
В этом посте мы расскажем о том, как настроить двухфакторную аутентификацию в Check Point Security Gateway с использованием электронных ключей на примере JaCarta PKI российского разработчика решений по информационной безопасности.

О том, что удалённый доступ к ресурсам организации несёт пользу, но и создаёт ряд проблем для IT-департамента, говорится везде очень много. Мы также считаем это важной темой. Поэтому решили посвятить этому следующий пост.

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

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

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

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

JaCarta Client


JaCarta Client — программное обеспечение, позволяющее строить инфраструктуру с открытыми ключами с применением ключевых носителей JaCarta PKI. Данное программное обеспечение позволяет применять защищённую передачу информации, основанную на инфраструктуре открытых ключей.

Электронные ключи могут поставляться в различных форм-факторах, включая USB-токены, смарт-карты, в т.ч. с широкими возможностями кастомизации (нанесение логотипа, использование корпоративного стиля и т.д.). Все форм-факторы управляются единым интерфейсом, программным обеспечением JaCarta Client. JaCarta Client имеет унифицированные методы работы, такие, как PKCS#11, CAPI, которые обеспечивают поддержку множества приложений «из коробки», поддерживающих данные интерфейсы. Поддерживаются такие сценарии, как защищённый Web-вход, защищённый вход в систему, шифрование данных, шифрование почты. PKI ключи и сертификаты могут быть созданы, размещены и использованы наиболее безопасным способом при помощи аппаратных либо программных токенов.

В комплексе с ключами чаще всего используется JaCarta Management System, обеспечивающая организации комплексную платформу управления жизненным циклом ключей. JMS связывает идентификаторы с пользователями, позволяя контролировать сертификаты, используемые ими. JMS позволяет масштабировать систему без угрозы нарушения работы.

Check Point Security GateWay защищает внутренние и внешние сети, публичные и приватные облака от внутренних и внешних угроз безопасности, защищая виртуальные машины и приложения при помощи полного набора инструментов защиты Check Point Software Blades.

В этом посте мы подробно опишем шаги по настройке поддержки входа в удалённую сеть по сертификату пользователя при помощи смарт-карты, либо аппаратного токена JaCarta PKI. Подразумевается, что Check Point Security GateWay окружение уже настроено на статические пароли пользователей для аутентификации.

Требования к ПО


Информация в посте применима к:

  • JaCarta Client — программное обеспечение, управляющее токенами JaCarta разработки «Аладдин Р.Д.»;
  • Check Point Security GateWay.


Окружение


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

  • JaCarta PKI Client
  • CheckPoint GAIA
  • CheckPoint Endpoint Security Client

Кому будет интересно то, о чём мы расскажем дальше


По сути, инструкция, о которой пойдёт речь далее, будет интересна системным администраторам, кто знаком с семейством Check Point Security Gateway и заинтересован в использовании возможностей многофакторной аутентификации при помощи смарт-карт и USB-токенов JaCarta.

Аутентификация при помощи сертификатов с использованием JaCarta PKI Client.



Схема ниже демонстрирует сценарий аутентификации по сертификату.

Пользователь соединяется с Check Point Security Gateway Appliance при помощи клиентского приложения Check Point Security Gateway. Пользователь вставляет токен JaCarta PKI, на котором расположен его сертификат, вводит PIN-код токена.

После успешной аутентификации пользователь получает доступ к внутренним сетевым ресурсам.

Предварительные требования


Здесь описываются предварительные требования, которые необходимо удовлетворить прежде, чем приступать к настройке двухфакторной аутентификации по сертификатам для Check Point Security Gateway с использованием JaCarta PKI.

Для использования аутентификации по сертификатам необходимо установить и настроить Microsoft Certificate Authority. В качестве Удостоверяющего центра может быть использован любой УЦ, но в данном документе рассматривается именно Microsoft CA.

Пользователи должны иметь токены JaCarta PKI с выпущенными подходящими сертификатами на них.

JaCarta PKI Client версии 6.30 и выше должно быть установлено на компьютерах пользователей.

Поддерживаемые токены и смарт-карты


USB-токены:

  • JaCarta PKI;
  • JaCarta PKI/Flash;
  • JaCarta PKI/ГОСТ;
  • JaCarta PKI/ГОСТ/Flash.

Смарт-карты:

  • JaCarta PKI;
  • JaCarta PKI/ГОСТ.


Для смарт-карт требуется считыватель ASEDriveIII USB.

Настройка Check Point Security Gateway


Check Point SmartDashboard может быть использовано для настройки CheckPoint SSL VPN или IPSec VPN.

Настройка Check Point Security Gateway требует выполнения ряда действий.

  • Создание учётной записи пользователя и выпуск регистрационного ключа.
  • Создание группы пользователей.
  • Разрешение аутентификации для клиентов VPN.
  • Установка политики.
  • Установка сертификата.
  • Разрешение контроля удаления смарт-карты.

Создание пользователя и выпуск ключа регистрации


Пользователь создаётся с определённой схемой аутентификации для входа на Check Point Security VPN Client. Затем администратор инициирует процесс выпуска сертификата на Security Management Server и получает ключ регистрации.

  • Откройте Check Point SmartDashboard R77.
  • На экране логина заполните следующие поля и нажмите «Login».
  • Username — введите имя пользователя.
  • Password — введите пароль для пользователя.
  • Servername or Server IP Adress — выберите имя или IP-адрес сервера, где Check Point Security Gateway расположен.



  • В главном окне Check Point SmartDashboard, под Check Point SmartDashboard, кликните по Users и затем кликните по New User > Default.



  • В окне параметров пользователей в поле имени пользователя введите имя пользователя.



  • Кликните по Certificates.



  • Кликните по New, затем выберите Registration Key for certificate enrollment.
  • В окне Registration Key for Certificate Enrollment отображается ключ регистрации.
  • Скопируйте данный регистрационный ключ, сохраните его — он понадобится для дальнейшей регистрации.



  • В окне параметров пользователя, в списке сертификатов, добавляется ожидающий установки сертификат. Нажмите ОК.



Создание группы пользователей


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

Создание групп позволяет назначать задачи определённым пользователям. Шлюз не позволяет определить правила для определённых пользователей, но Вы можете назначать определённые правила группам пользователей.

  1. В главном окне Check Point SmartDashboard, под Users and Administrators, правый клик по User Groups, а затем New Group.



  2. В окне Group Properties заполните следующие поля, а затем кликните ОК.
  3. Name — введите имя группы, например, VPN_Group.
  4. Available Members/Selected Members — в списке доступных членов выберите членов для добавления в группу, затем кликните Add. Выбранные члены будут перемещены в список Selected Members.



Разрешение аутентификации для клиентов VPN



  • В главном окне Check Point SmartDashboard, под Network Objects, раскройте Check Point, правый клик по Вашему устройству, например, Checkpoint-ssl, затем клик по Edit.



  • В окне Check Point Gateway – Checkpoint-ssl, раскройте VPN Clients, затем кликните Authentication.



  • В Authentication Method выберите Defined on user record (Legacy Authentication) и затем клик по OK.


Настройка правил фильтрации для VPN-клиентов


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

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

  • В главном окне Check Point SmartDashboard кликните по Firewall.



  • Кликните по Policy, затем по иконке Add rule at bottom. Строка добавится под меню Policy.



  • В колонке Name — правый клик по новой строке и затем Edit.



  • В окне Rule Name в поле Rule Name добавьте имя для правила, затем кликните по ОК.



  • В колонке Destination — правый клик по новой строке, затем клик по Network Object.



  • В окне Add Object выбрать Internal_network. Internal_network — синоним к корпоративной сети предприятия.



  • В колонке VPN — правый клик по новой строке, затем Edit Cell.
  • В окне VPN Match Conditions выполните следующие шаги и нажмите ОК.
  • Выбрать Only connections encrypted in specific VPN communities, нажать ADD.



  • В окне Add Community to rule выбрать RemoteAccess и нажать ОК.



Новая политика создана.



Установка политики


  • Процесс установки политики приведён ниже.
  • Провести эвристическую проверку правил для того, чтобы убедиться в совместимости и в неизбыточности правил.
  • Подтвердить, что каждый шлюз безопасности, к которому будет применено правило, обеспечивает соблюдение, по крайней мере, одного правила.
  • Преобразование Политики безопасности в скрипт контроля и скомпилировать этот скрипт в инспекционный код.
  • Доставить инспекционный код на все выбранные объекты для доставки.
  • В главном окне Check Point SmartDashboard — клик по Install Policy сверху (в меню).



  • В окне Install Policy в колонке Network Security выбрать опции для требуемого устройства и кликнуть ОК.



  • Когда политика установится, нажать Close.



Установка сертификата


Клиент устанавливает защищённое соединение с внутренним Удостоверяющим центром Check Point, запрашивает сертификаты с помощью ключа регистрации. Запрашивая сертификат пользователя впервые, предоставьте ключ регистрации и установите сертификат на токен.

  • Вставьте JaCarta PKI в слот USB, затем откройте приложение Check Point Endpoint Security.
  • IP-адрес в поле Site тот же, что был введён в ходе установки. Также в ходе установки в качестве опции аутентификации были выбраны сертификаты. Клик по ссылке Click here if you don’t have a certificate for this site.



  • В поле Provider выберите Athena Smart Card CSP.



  • В поле Registration Key введите сохранённый ранее ключ регистрации, нажмите Enroll.
  • В окне Token Logon в поле Token Password введите PIN-код пользователя от используемой JaCarta PKI, затем нажмите ОК.
  • Сообщение системы безопасности предложит установить новый корневой сертификат, нажмите YES. Данный сертификат принадлежит Удостоверяющему центру Check Point Internal.



  • Когда установка завершится, нажмите ОК.



  • Откройте JaCarta PKI Client и убедитесь в том, что сертификат был успешно выпущен.



Контроль за извлечением смарт-карты



  • На шлюзе Check Point Gateway необходимо отредактировать файл
    $FWDIR/conf/trac_client_1.ttm, используя редактор VI либо любой другой.
  • Далее необходимо найти строку disconnect_on_smartcard_removal.
    *:disconnect_on_smartcard_removal (
    gateway (
     :default (true) 
    ) 
    )* 

  • Изменить параметры по умолчанию в соответствии с требованиями:
    • true — разрешить детектирование извлечения смарт-карты для текущего шлюза;
    • false — запретить детектирование извлечения смарт-карты для текущего шлюза;
    • client_deside — разрешить пользователю самостоятельно устанавливать параметр детектирования извлечения смарт-карты для текущего шлюза.

  • Далее необходимо сохранить файл и выйти из режима редактирования.
  • Установить политику, используя Smart DashBoard.
  • На компьютере, являющимся клиентским, откройте окно параметров Check Point Endpoint Security и поставьте галку напротив Enable always-connect.




Вход на шлюз


Откройте приложение Check Point Endpoint Security.

  • Вставьте JaCarta PKI. Сертификаты на токене будут отображаться в поле Certificate. Нажмите Connect.



  • В окне Token Logon в поле Password введите PIN-код от токена и нажмите ОК.
  • В панели задач кликните иконку VPN для просмотра статуса подключения. Когда аутентификация проходит успешно, статус соединения становится Connected.


Подобные и другие интересные проекты в «Аладдин Р.Д.» ведёт отдел по работе с технологическими партнёрами.

В настоящее время мы расширяем штат специалистов, и у нас есть вакансия в этом отделе — Инженер по работе с партнёрами/пресейл-инженер.

Если Вас заинтересовала работа в компании «Аладдин Р.Д.», пожалуйста, пришлите Ваше резюме с указанием желаемой позиции на адрес job@aladdin-rd.ru .

Будем рады вашим откликам!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335250/



Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1088 1087 [1086] 1085 1084 ..
.. 1 Календарь