Отслеживание сетевого трафика между подами в Kubernetes

Как работает связь между подами в Kubernetes? Как трафик достигает пода?

В этой статье вы узнаете, как работает низкоуровневая сеть в Kubernetes.

Давайте начнем с того, что сосредоточимся на сети модулей и узлов.

При развертывании пода происходит следующее:

  1. Модуль получает собственное сетевое пространство имен.

  2. Присваивается IP-адрес.

  3. Все контейнеры в модуле используют одно и то же сетевое пространство имен и могут видеть друг друга на localhost.

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

Это достигается с помощью виртуальной пары eth, соединяющей 2 пространства имен: pod и root.

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

Так что же происходит, когда Pod-A хочет отправить сообщение Pod-B?

Поскольку пункт назначения не является одним из контейнеров в пространстве имен, Pod-A отправляет пакет на свой интерфейс по умолчанию eth0.

Этот интерфейс привязан к паре veth, и пакеты перенаправляются в корневое пространство имен.

Мост ethernet, действующий как виртуальный коммутатор, должен каким-то образом преобразовать IP-адрес целевого модуля (Pod-B) в его MAC-адрес.

На помощь приходит протокол ARP.

Когда кадр достигает моста, всем подключенным устройствам отправляется широковещательная рассылка ARP.

Мост кричит: «У кого есть IP-адрес Pod-B?»

Получен ответ с MAC-адресом интерфейса, соединяющего Pod-B, который хранится в кэше ARP моста (таблица поиска).

После сохранения сопоставления IP- и MAC-адресов мост просматривает таблицу и пересылает пакет в нужную конечную точку.

Пакет достигает Pod-B veth в корневом пространстве имен, а оттуда быстро достигает интерфейса eth0 внутри пространства имен Pod-B.

При этом связь между Pod-A и Pod-B была успешной.

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

Это «простая» сетевая версия.

Как это меняется при установке подключаемого модуля CNI, использующего оверлейную сеть?

Возьмем, к примеру, фланель.

Flannel устанавливает новый интерфейс между узлом eth0и мостом контейнера cni0.

Весь трафик, проходящий через этот интерфейс, инкапсулируется (например, VXLAN, Wireguard и так далее).

В новых пакетах в качестве источника и получателя указаны не IP-адреса модулей, а IP-адреса узлов.

Таким образом, пакет-обёртка выйдет из узла и отправится к узлу назначения.

Оказавшись на другой стороне, flannel.1 интерфейс разворачивает пакет и позволяет исходному pod-to-pod пакету достичь места назначения.

Откуда Flannel знает, где находятся все модули и их IP-адреса?

На каждом узле Flannel синхронизирует распределение IP-адресов в распределенной базе данных.

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


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

Курс 👉 «Kubernetes Мега» на нашем сайте.


ссылка на оригинал статьи https://habr.com/ru/companies/southbridge/articles/738920/

MariaDB, фрагментация, varchar и печалька

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

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

Ситуация

Вводная часть

Есть проект, код и БД спроектированные и реализованные аутсорсерами junior’ми, есть новая инхаус команда разработки и 100500 проблем. Как обычно бывает в такой ситуации задач много, ресурсов мало, надо делать новое, молится чтобы не развалилось старое, наводить порядок во всём. Суть проекта коротко – есть портал и api для создания, сохранения, редактирования, настройки ядра волшебной системы, которая приносит деньги. Настройки надо собрать, скомпоновать, немного отформатировать и отправить в виде большого XML файла.

Для тех у кого возник вопрос — зачем файл?

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

схема бизнеса

схема бизнеса

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

Технические вводные

База данных: MariaDB 10.4
Engine: InnoDB, буфер до 12GB
Размер БД: 28 GB
Машина: 8 ядер, 32 RAM, SSD
На машине работают и другие сервисы, CPU ниже 30% не падает, оперативная память в пике занята полностью, la ниже 4 не опускается.

Для тех у кого возник вопрос — почему не добавить машин?

Деньги. Особая экономия на всём что не грозит падением ядру.

Время генерации файла настроек от 20 до 40 минут. Большая часть времени генерации — выборки из БД. Самая продолжительная выборка связана с таблицей, хранящей неделимые сущности, назовём её sections. В таблице инкрементальный  id типа int и 36 столбцов, 7 столбцов типа varchar, остальные фиксированной длинны флаги-tinyint, int, enum, float. Самая большая по количеству записей и чтений таблица, количество строк от 2 млн до 4+ млн.

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

Развитие ситуации

График развития ситуации

 y – секунды  генерации, x – годы

y – секунды  генерации, x – годы

Фаза 1 – аутсорсеры. Данных относительно немного, но объем данных постоянно растёт. Что тут было рассказать не могу, но и так видно что скучно не было.

Фаза 2 – начало инхаус разработки, данных всё больше, добавляются новые сущности в файл настройки. Приходят большие клиенты, ужесточаются требования к стабильности сервиса.
Уменьшение времени генерации происходило после ALTER’ов с добавлением полей таблицы sections, что объяснимо тк такая операция приводит к перестроению таблицы, своего рода recreate+analyze. (Напомню что данные из таблицы не удалялись.) Процесс на загруженной машине не быстрый и приводит к блокировке таблицы, отчего часть функций проекта не работала довольно продолжительное время. Поэтому старались таблицу не трогать.
Красными линиями обозначена тенденция на увеличение времени генерации файла, как видно не самая радужная.
Долго ли коротко ли, ситуация привела к катастрофе, обозначенной пиком, за которым последовал полный отказ генератора, который график не отображает, так как регистрирует только удачные генерации.
Тут ваш покорный слуга был вынужден заняться вопросом серьёзно. Внезапно и руководство решило что вопрос надо решать, вроде не стартап уже.

Фаза 3 – борьба с последствиями падения, вынужденный recreate таблиц.
Видно что время генерации упало до докатастрофических времён, однако скорость нарастания времени генерации не предвещала ничего хорошего.
Изучение запросов, структуры таблиц, действий партнёров и истории событий.

Фаза 4 – ALTER с отказом от varchar для части столбцов в таблице sections и части связанных таблиц.
Скучная стабильная жизнь БД. Без alter и recreate. Объем данных растёт сравнимыми с предыдущими периодами темпом.

Фаза 5 – решаем проблемы скучно, по взрослому.
Слейв, отдельная машина, перенос генератора на крайние версии языка, много RAM, незагруженный SSD. Даже перечислять неинтересно и сказ совсем не про это.

Отказ от varchar – полностью исправил ситуацию

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

Технический разбор ситуации

Фрагментация таблицы.

InnoDB хранит данные в страницах по 16k (по дефолту), в странице содержится столько строк сколько может поместиться в этот объем, индекс содержит указание на страницу в которой хранятся данные. Страницы с данными при этом размещаются в файле данных по primary key. (Более подробно о механизме можно почитать тут .) Такая организация данных может привести к фрагментации таблицы при операциях изменения/добавления данных.

Итак в нашем случае фрагментация не может возникнуть:
– при delete, тк строки из таблицы не удаляются;
– при insert тк всегда вставляются новые сущности с большим id.
Возникает она из-за update и того что в строке есть varchar.

Как происходит фрагментация при update.
Пусть у нас есть таблица test из 3х столбцов id int pk, name varchar(10), val int, при этом страница InnoDB допустим вмещает 2 строки длины 2 int +4 символа

наши 2 страницы

наши 2 страницы

Итого у нас 2 страницы на 3 записи, индекс с двумя страницами и данные в файле уложены последовательно.

Далее UPDATE test SET name=’row1new’ WHERE id=1 строка стала длиннее и не помещается не только на место старой строки с id=1, но и в страницу в целом. Для того чтобы данные были уложены по pk надо разместить строку после апдейта в начало, но это невозможно. Значит данные надо уложить по другому, например id=1 перенести на новую страницу так

2 страницы превратились в 3

2 страницы превратились в 3

Индекс при этом будет для id=1 указывать на страницу 3, для id=2 на страницу 1, а для id=3 на страницу 2. В первой и третьей странице при этом образуется свободное место, которое не может быть занято, тк укладка данных по pk будет нарушена.
В итоге мы получили 3 страницы вместо двух, удлинение индекса с уменьшением его эффективности, данные уложенные непоследовательно, что ухудшает скорость чтения с диска.

Частота, задержки и характер изменения строк с varchar

В нашей ситуации и при проектировании таблиц – это немаловажный параметр для выбора типа данных в нагруженной таблице. Рассмотрим 2 фактора:
1) уменьшение или увеличение длинны строки varchar;
2) задержка update’а строки.

По пункту 1. Если строка уменьшится то не надо менять индекс и не надо создавать/пересобирать страницы. Например для нашей таблицы test сделаем UPDATE test SET name=’r1′ WHERE id=1, в первой строке появятся 2 свободные позиции, никаких изменений индекса или положения данных.
Проверим это на реальной БД, создаем таблицу

create of test

CREATE TABLE ‘test’ (
‘id’ int(11) NOT NULL AUTO_INCREMENT,
‘name’ varchar(10) NOT NULL,
‘val’ int(11) NOT
создаем в ней 2 записисоздаем в ней 2 записисоздаем в ней 2 записи NULL,
PRIMARY KEY (‘id’)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=ascii COLLATE=ascii_general_ci
 

создаем в ней 2 записи

пойдём смотреть что в файле

и обнаружим что файл пуст.

Вот тут мы подошли к пункту 2. СУБД не пишет данные на диск сразу, сначала данные накапливаются в буфере, где они могут быть выровнены и отсортированы перед записью на диск и проблемы фрагментации не будет. Давайте заставим СУБД записать данные. Смотрим

Вот наши строки в файле.

Делаем UPDATE test SET name=’r1′ WHERE id=1 и видим в файле

строка 2 не сместилась, строка 1 осталась на месте, просто длинна её уменьшилась на 2 символа и образовалось свободное место.

Сделаем UPDATE test SET name=’row1new’ WHERE id=1, смотрим в файл

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

В рассматриваемой ситуации  строки вставлялись либо с пустыми значениями для полей типа varchar, либо со значениями минимальной длины. Затем по прошествии времени достаточного для заполнения страницы InnoDB данные обновлялись, что приводило к необходимости изменения страниц. Практически во всех сценариях, где строка изменялась — длина строковых значений увеличивалась с задержкой относительно момента вставки, для одного или нескольких столбцов.

На практике это выглядело так – большой клиент через api создавал группу сущностей с пустыми значениями типа varchar для того чтобы получить id сущности. Затем для полученных id в его системе формировались настройки, идентификаторы и проводилась интеграция с другими сервисами. После всех этих операций сущность в нашей системе получала текстовый идентификатор(varchar) значительной длины, настройки(varchar) и активировалась. И далее в процессе жизни записи значения varchar старых записей могли увеличиваться за счёт добавления указателей в текстовый идентификатор записи. Через интерфейс процесс мог выглядеть примерно так же, но объемы были незначительны. Таким образом заводилось от 30 до 50% записей.

Эксперимент

Создадим таблицу побольше test_data_varchar_with_update с одним изменяемым полем ‘name’ varchar(255)

create of test_data_varchar_with_update

CREATE TABLE ‘test_data_varchar_with_update’ (
‘id’ bigint(20) unsigned NOT NULL AUTO_INCREMENT,
‘id_pointer’ varchar(100) DEFAULT NULL,
‘width’ int(10) unsigned NOT NULL DEFAULT 0,
‘height’ int(10) unsigned NOT NULL DEFAULT 0,
‘name’ varchar(255) NOT NULL,
‘parent_id’ int(10) unsigned NOT NULL,
‘price’ double unsigned NOT NULL DEFAULT 0,
‘price_typ3’ char(10) NOT NULL DEFAULT ”,
‘category’ int(10) unsigned DEFAULT NULL,
‘price_split’ double unsigned NOT NULL DEFAULT 0,
‘fall_num’ int(10) unsigned NOT NULL DEFAULT 0,
‘fall_enable’ tinyint(4) NOT NULL DEFAULT 0,
‘player’ enum(‘p1′,’p2′,’pp’) NOT NULL DEFAULT ‘p1’,
‘position_x’ enum(‘left’,’center’,’right’) NOT NULL,
‘position_y’ enum(‘top’,’center’,’bottom’) NOT NULL,
‘c_id’ int(11) DEFAULT 0,
‘control’ enum(‘Manual’,’Auto’) DEFAULT ‘Auto’,
‘is_r’ tinyint(4) NOT NULL DEFAULT 0,
PRIMARY KEY (‘id’)
) ENGINE=InnoDB DEFAULT CHARSET=ascii COLLATE=ascii_general_ci 

Вставим миллион записей в таблицу со средней длинной строки в колонке name в 5-10 символов, после вставки тысячи записей обновим тридцать процентов строк, перезаписав колонку name строками длинной 11-255 символов.

псевдокод вставки

for (i=1; i < 1000001; $i++){
INSERT INTO test.test_data_varchar_with_update(…, name, …)VALUES(… ‘rowNi’, …”);
if(i % 1000 == 0){
for (j=0; j < 300; j++){
exec(“UPDATE test.test_data_varchar_with_update SET name = ‘”randString(rand(11,255))”‘ where id=”rand(i-1000,i));
}
}
}

Создадим её копию test_data_varchar_no_update и внесём в неё данные  из таблицы test_data_varchar_with_update импортом.

Для сравнения создадим копию test_data_char на основе test_data_varchar_with_update, но поле ‘name’ сделаем типа char(255)  и внесём в неё данные  из таблицы test_data_varchar_with_update импортом.

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

таблица с апдейтами практически на 45% больше (что ожидаемо тк по дефолту MERGE_THRESHOLD установлен в 50%). Таблица с фиксированной длиной строки больше всех, тк под строку всегда выделяется 255 байт, однако разница между таблицей с апдейтами не так уж и велика.

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

скрин из *no_update

последняя запись на первой странице с id=81.
Теперь в файл таблицы с апдейтом

скрин из *with_update

последняя запись на первой странице с id=78, разрыв между страницами явно больше и может содержать несколько строк. Это разрыв возможно никогда не будет заполнен.

А что со скоростью выборки из 3х указанных таблиц?
(Во всех тестах InnoDB буфер значительно меньше таблиц.)
Сделаем скрипт который выбирает 100 случайных id в цикле 100 раз. Выведем среднее время исполнения для запроса.

Cycle random, Cycles:100, Ids: 100
Table test_data_varchar_with_update: 0.017486 sec
Table test_data_varchar_no_update: 0.014363 sec
Table test_data_char: 0.016273 sec

Сделаем скрипт выбирающий 1000 последовательных id в цикле 100 раз. Выведем среднее время исполнения для запроса.

Cycle diapason, Cycles:100, Ids: 1000
Table test_data_varchar_with_update: 0.006068 sec
Table test_data_varchar_no_update: 0.005136 sec
Table test_data_char: 0.005806 sec

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

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

Cycle random, Cycles:100, Ids: 100
Table test_data_varchar_with_update:0.453521 sec
Table test_data_varchar_no_update: 0.169505 sec
Table test_data_char: 0.170396 sec

Таблицы с char и no_update менее склонны к значительному изменению времени исполнения относительно друг друга.

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

Технический итог

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

Заключение

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

Если таблица в БД после recreate начинает работать быстрее, но при этом начинает быстро уставать – посмотрите есть ли в ней поля переменной длины и насколько часто они меняются, возможно изменение типа varchar на char решит вашу проблему.

В представленной ситуации это решение оказалось удивительно эффективным.


ссылка на оригинал статьи https://habr.com/ru/articles/738898/

Как в США и Канаде стимулируют инновации и изобретательскую активность: обзор законов и практик

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

Проработанное законодательство 

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

Многие законы об инновациях в США были приняты после холодной войны. В конце 80-х годов расходы на НИОКР повышались, но результативность государственных вложений упала. Для стимулирования инновационной активности и использования результатов НИОКР был принят ряд законов, в том числе уточняющих передачу прав:

  1. Исследовательские центры и предприниматели стали правообладателями изобретений, созданных в ходе финансируемых государством исследований (Закон Бейха-Доула);

  2. Определили распределение прав на изобретения при сотрудничестве частных предприятий и государственных центров и лабораторий (Закон Стивенсона-Видлера); 

  3. Институты и национальные лаборатории получили право владеть патентами и коммерциализировать их. 

В итоге, если до изменений коммерциализировалось только 5% государственных патентов, то после этот показатель вырос до 30%. Поступления в бюджет только от налогов с продажи лицензий оценивались в 5 млрд долларов. 

Также в США у предприятий есть право «shop right». Права на разработку всегда остаются у работника, если только он изначально не нанимался с целью изобретать. Однако у фирмы есть право использовать изобретение по условиям неисключительной лицензии, без выплаты автору вознаграждения. 

Свобода торговли, миграции и технологического обмена 

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

Многие из иностранных студентов создали полезные для экономики инновации после выпуска. Те, кто после обучения вернулся на родину, часто заключали контракты с американскими фирмами, научными центрами, государственными структурами. В одном из исследований было показано, что в период с 1940 по 2000 год увеличение доли выпускников колледжей-иммигрантов на 1% увеличивало число патентов на душу населения на 9-18%! 

Points scored

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

Налоговые льготы

В Канаде налоговые льготы устроены так, чтобы максимально увеличить приток средств на исследования внутри страны. Существует программа «Научные исследования и экспериментальные разработки». Компании-участники могут получить налоговый вычет в 20-35% с первых двух миллионов долларов. Однако воспользоваться предложением можно только, если эти деньги будут потрачены на исследования исключительно внутри Канады.

Более того, компании могут списывать из налогооблагаемого дохода расходы на НИОКР и оборудование для исследований. Если фирма собирается инвестировать в НИОКР на территории страны, то она может платить на 20% меньше налогов и использовать эти деньги на разработки. Для малых и средних предприятий компенсация доходит до 35%. 

Одна из самых неэффективных систем снижения расходов на НИОКР находится в США (в сравнении с развитыми странами). На 2018 год программы по снижению затрат на НИОКР позволяли добиться сокращения стоимости примерно на 5%, в то время как во Франции, Португалии и даже Чили аналогичный показатель мог достигать 30%. При этом в Штатах может быть компенсировано до 50% затрат на патентование для независимых изобретателей, малых фирм и некоммерческих организаций — на этих условиях в стране выдается около четверти всех патентов. 

Также стоит учитывать, что в процентах от ВВП Америка все еще тратит достаточно много на поддержание НИОКР для бизнеса. Как показано на диаграмме ниже, среди всех стран-участниц ОЭСР по объему поддержки НИОКР США в 2020 году были на 13 месте. Однако многим другим развитым странам, а также России, Штаты по этому показателю сильно уступали. 

Прямое государственное финансирование и налоговая поддержка НИОКР для бизнеса, 2020 год в процентах от ВВП. Источник 

Прямое государственное финансирование и налоговая поддержка НИОКР для бизнеса, 2020 год в процентах от ВВП. Источник 

В США налоговая система устроена так, что компания платит меньше отчислений за приобретение патента, чем за выплату зарплаты. Поэтому предприятиям рекомендовалось увеличивать гонорар работникам за их готовность передать интеллектуальные права. Такая система “патентных ящиков” сильно критикуется. По мнению некоторых специалистов, это приводит только к перемещению патентов фирм в разные юрисдикции и к налоговому мошенничеству. 

Поддержка малых предприятий программой SIBR

Программа SBIR позволяет малым предприятиям развиваться в технологиях сферы здравоохранения, безопасности, окружающей среды, энергоэффективности и альтернативной энергетики. Государство объявляет потребность в конкретной технологии, после чего компании представляют свои разработки. Отсев участников проводится в два этапа. На первом принимается не более 15%, а на втором — около 50%. 

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

Впервые SIBR была запущена в 1982 году и разрослась до 11 федеральных агентств, которые обязаны выделять 2,5% своего бюджета на спонсирование контрактов с малыми предприятиями (штат сотрудников до 500 человек). Сейчас бюджет программы уже превысил 2 млрд долларов. Эти агентства ежегодно составляют перечень научных и технологических проблем, в решении которых заинтересованы. В ответ предприятия высылают свои решения проблем. Проводится конкурс на получение гранта.

Технология создается в три этапа:

  1. Грант в размере 100 000 долларов на технико-экономическое обоснование. Компании проводят ограниченные исследования для определения научной и коммерческой перспективности;

  2. Грант около 750 000 долларов на более масштабные исследования и разработку проектов;

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

Ежегодно примерно третью участников SBIR становятся новички.

Результаты государственной поддержки 

В одном из своих докладов ВОИС указывает несколько наиболее значимых примеров позитивного вмешательства государства в развитие технологий:

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

Полупроводники. Здесь использовался целый ряд решений:

  1. В конце 50-х годов XX века около четверти всех расходов на НИОКР приходилась на проект центра Bell Labs по проведению исследований. Высокий уровень инвестиций сохранялся вплоть до проекта SEMATECH 1987 года. 

  2. Государство поощряло сотрудничество организаций, в том числе конкурирующих, а также укрепляло связь между производителями и исследователями. Был принят Национальный закон о проведении совместных исследований 1984 года. 

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

  4. Активно проводилась стандартизация, за счет чего местные компании смогли выйти на более широкий рынок. 

  5. Проводилась политика “покупай американское”, за счет которой результаты исследований было проще коммерциализировать. 

Изменение объема и доли продаж в сфере полупроводниковой промышленности в США и в остальном мире. Источник

Изменение объема и доли продаж в сфере полупроводниковой промышленности в США и в остальном мире. Источник

3D-печать. США вложили около 50 млн долларов для запуска массового производства и партнерства между государством и частными компаниями. В это партнерство на 2015 год входило около 50 компаний, 28 институтов и лабораторий, 16 других организаций. 

Также значимой оказалась стандартизация. Для технологий аддитивного производства был создан специальный комитет F42, а в 2012 году был запущен проект “America Makes” — международная организация по стандартизации. Они разработали новый формат файла для передачи информации. Если фактический отраслевой стандарт на тот момент позволял передавать данные только о поверхностной сетке, то новый формат позволял передавать текстуру, подструктуру, цвет и другие свойства. 

Нанотехнологии. Среди всех государственных программ прямого финансирования нанотехнологий Национальная нанотехнологическая инициатива в США 2000 года стала самой первой и крупной. Всего на исследования и разработки было выделено порядка 4 млрд долларов.  

Итоги

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

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

P.S. В нашем телеграм-канале мы разыгрываем бесплатную регистрацию товарного знака и другие призы. Приглашаем принять участие.

О сервисе Онлайн Патент

Онлайн Патент – цифровая система №1 в рейтинге Роспатента. С 2013 года мы создаем уникальные LegalTech-решения для защиты и управления интеллектуальной собственностью. Зарегистрируйтесь в сервисе Онлайн-Патент и получите доступ к следующим услугам:

  • Онлайн-регистрация программ, патентов на изобретение, товарных знаков, промышленного дизайна;

  • Подача заявки на внесение в реестр отечественного ПО;

  • Опции ускоренного оформления услуг;

  • Бесплатный поиск по базам патентов, программ, товарных знаков;

  • Мониторинги новых заявок по критериям;

  • Онлайн-поддержку специалистов.

Больше статей, аналитики от экспертов и полезной информации о интеллектуальной собственности в России и мире ищите в нашем Телеграм-канале.

Получите скидку в 2000 рублей на первый заказ. Подробнее в закрепленном посте.


ссылка на оригинал статьи https://habr.com/ru/companies/onlinepatent/articles/738960/

Психологическая безопасность в команде

Артем Михайлов

Автор статьи

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

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

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

Что такое психологическая безопасность?

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

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

Основный аспекты психологической безопасности:

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

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

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

Основные проблемы

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

  1. Негативное межличностное взаимодействие

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

  2. Стресс

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

  3. Окончательный результат

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

  4. Нежелание говорить о своих проблемах:

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

  5. Низкий уровень мотивации

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

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

Как обеспечить психологическую безопасность?

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

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

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

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

Также элементом обеспечения психологической безопасности является отбор команды. Каждый новый член команды должен быть предварительно проверен на соответствие профессиональным и личностным требованиям. Это поможет избежать конфликтов и недопонимания между членами команды.

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

Несколько советов в каждому члену команды:

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

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

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

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

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

Заключение

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

Завершить статью хочу полезной рекомендацией:

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

На вебинаре преподаватели OTUS расскажут в чем смысл рисков и зачем ими управлять. Зачем риск-менеджмент тимлиду, как управлять рисками, чтобы в этом были смысл и польза.

Зарегистрироваться на бесплатный вебинар


ссылка на оригинал статьи https://habr.com/ru/companies/otus/articles/738972/

Как обрабатывать ошибки в Golang – рассказываем на собственном примере

Всем привет. Меня зовут Алексей Бурмистров, я senior Golang разработчик в Quadcode. В процессе разработки биллинга, мы столкнулись с различными типами ошибок, которые могут возникать во время выполнения программы. В данной статье я хочу поделиться нашим опытом в структурировании и обработке этих ошибок, а также представить подходы, которые мы применили для их эффективной обработки и диагностики. Наша основная цель заключается в создании понятных и легко обрабатываемых ошибок, которые гарантируют надежную работу биллинга.

Ошибки это один из самых важных аспектов любого языка программирования. То, как обрабатываются ошибки, влияет на приложения многими способами. То, как определяются ошибки в Golang, немного отличается от таких языков как Java, Python, Javascript. В Go ошибки – это значения.​

Свой тип ошибки

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

​Основой всего является тип Error– конкретное представление ошибки, который реализует стандартный интерфейс error. Он имеет несколько полей, некоторые из которых могут быть не заданы:

type errorCode string  // Коды ошибок приложения. const (  ... ENOTFOUND errorCode = "not_found" EINTERNAL errorCode = "internal" ... )  type Error struct { // Вложенная ошибка Err error `json:"err"` // Дополнительный контекст ошибки Fields map[string]interface{} // Код ошибки. Code errorCode `json:"code"` // Сообщение об шибке, которое понятно пользователю. Message string `json:"message"` // Выполняемая операция Op string `json:"op"` }
  • Op обозначает выполняемую операцию. Оно представляет собой строку, которая содержит имя метода или функции такие как repo.User, convert, Auth.Login и так далее.

  • Message содержит сообщение или ключ перевода ошибки, которое можно показать пользователю.

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

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

  • Err содержит вложенную ошибку, которая может быть связана с текущей ошибкой. Это может быть ошибка, возвращаемая внешней библиотекой или наша собственная Error

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

Создание ошибки

Для создания ошибки мы решили не делать отдельный конструктор, потому как структура не такая объемная. Для того чтобы разработчики не ошиблись при создании ошибки (например забыли & или не создали ошибку без Err и Message), мы используем собственный линтер для golangci-lint

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

func (r *userRepository) User(ctx context.Context, id int) (*User, error) { const op = "userRepository.User" ... }

Еcли нам нужно только добавить op к ошибке для передачи на верхний уровень мы можем воспользоваться вспомогательными функциями OpError или OpErrorOrNil

... var user User err := db.QueryRow(ctx, query, id) if err != nil {  if errors.Is(err, pgx.ErrNoRows) {   return nil, &app.Error{Op: op,Code: app.ENOTFOUND, Message: "user not found"}  }  return app.OpError(op, err) } ...

Обработка ошибок​

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

Для проверки Code есть вспомогательная функция ErrorCode которая возвращает код ошибки, если это была ошибка приложения, или EINTERNAL если это была другая.

switch ErrorCode(err) { case ENOTFOUND: ... case EINTERNAL: ... }

Если нам нужен полный доступ к Error можно воспользоваться стандартной библиотекой errors.

appErr := &Error{} if errors.As(err, appErr) {  ... }

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

Примерное преобразования ошибки в HTTP-статус:

var codeToHTTPStatusMap = map[errorCode]int{    ENOTFOUND: http.StatusNotFound,    EINTERNAL: http.StatusInternalServerError,    // Другие соответствия кодов ошибок и HTTP-статусов }  func ErrCodeToHTTPStatus(err error) int {    code := ErrorCode(err)    if v, ok := codeToHTTPStatusMap[code]; ok {        return v    }       // Возвращаем стандартный HTTP-статус для неизвестных ошибок    return http.StatusInternalServerError } 

Теперь, чтобы получить соответствующий HTTP-статус для ошибки, достаточно вызвать функцию ErrCodeToHTTPStatus и передать ошибку ей. Она вернет соответствующий HTTP-статус. Если код ошибки не найден, будет возвращен стандартный HTTP-статус http.StatusInternalServerError.

Анализ и диагностика​

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

  • code: тип ошибки, чтобы понять её характер;

  • msg: сообщение из Err.Error();

  • fields: контекст, добавленный к ошибке;

  • trace: стек трассировки операций.

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

goroutine 1 [running]: testing.(*InternalExample).processRunResult(0xc000187aa8, {0x0, 0x0}, 0x0?, 0x0, {0x1043760e0, 0x1043b8d88})        /opt/homebrew/Cellar/go/1.19.4/libexec/src/testing/example.go:91 +0x45c testing.runExample.func2()        /opt/homebrew/Cellar/go/1.19.4/libexec/src/testing/run_example.go:59 +0x14c panic({0x1043760e0, 0x1043b8d88})        /opt/homebrew/Cellar/go/1.19.4/libexec/src/runtime/panic.go:890 +0x258 app.foo(...)        app/errors_test.go:336 app.bar()        app/errors_test.go:341 +0x38 app.baz()        app/errors_test.go:345 +0x24 app.ExampleTrace()        app/errors_test.go:350 +0x24 testing.runExample({{0x1042f8cd5, 0xc}, 0x1043b8528, {0x1042fcab9, 0x19}, 0x0})        /opt/homebrew/Cellar/go/1.19.4/libexec/src/testing/run_example.go:63 +0x2ec testing.runExamples(0xc000187e00, {0x10450e080, 0x1, 0x0?})        /opt/homebrew/Cellar/go/1.19.4/libexec/src/testing/example.go:44 +0x1ec testing.(*M).Run(0xc00014a320)        /opt/homebrew/Cellar/go/1.19.4/libexec/src/testing/testing.go:1728 +0x934 main.main()

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

["ExampleRun", "baz", "bar", "foo"]

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

Для логирования мы используем пакет go.uber.org/zap. Для него мы сделали вспомогательную функцию Error(err error) zap.Field, которая позволяет нам легко логировать ошибку в виде объекта.

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

func foo() {    ...    if err != nil {        logger.Error("something gone wrong", Error(err))    } } 

Пример вывода ошибки в логе может выглядеть следующим образом:

{"level":"error","msg":"something gone wrong","error":{"msg":"user not found","code":"not_found","trace":["userRepository.User"],"fields":{"user_id":"65535"}}}

Финальные выводы

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

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

Если вы хотите ознакомиться с примерами кода, вы можете найти их в GitHub.

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


ссылка на оригинал статьи https://habr.com/ru/companies/quadcode/articles/738944/