RSS

Комментарии

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

— 3D-технологии для внедрения новых инструментов Data Visualization, показа большего числа данных, в том числе с привязкой к географии

— XR для совместной работы и визуализации аналитики в интерактивном иммерсивном формате.
За какими технологиями нужно следить, чтобы быть в курсе развития BI-систем?
Я бы выделил целый ряд трендов:

— MD/MQ Data management

— Внедрение data-driven культуры в работу

— Внедрение self-service BI систем

— Data Visualization

— Data Storytelling

— Развитие ABI систем

— Аналитика в real time

— Data warehouse modernization

— Data governance

— Предиктивная аналитика

— Внедрение моделей машинного обучения

— Cloud BI

— Самостоятельная работа с данными

— BI-системы для мобильных устройств

— Добавление и совершенствование уведомлений в BI-системах

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

Бизнес-аналитика становится проще и доступнее, и развитие технологий только способствует этому.
Как материализованные представления в потоковой базе данных с CDC-подходом и шаблоном CQRS позволяют реализовать масштабируемую и высокопроизводительную систему с микросервисной архитектурой для транзакций и аналитики данных в реальном времени. Разбираемся с паттернами проектирования микросервисов на примере интернет-магазина.
Что не так с шаблоном композиция API и другие проблемы микросервисной архитектуры в управлении данными

Микросервисная архитектура для распределенных систем позволяет обеспечить гибкость, масштабируемость и отказоустойчивость. Однако, как мы уже упоминали здесь, запрос данных из нескольких микросервисов в режиме реального времени может оказаться сложной задачей, поскольку для этого могут потребоваться сложные и трудоемкие операции извлечения данных. Материализованные представления вместе с паттерном проектирования разделения ответственности команд и запросов (CQRS, Command Query Responsibility Segregation) могут решить эту проблему, обеспечивая эффективный запрос данных микросервисов в режиме реального времени.

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

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

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

Однако, для GraphQL характерны риски доступа клиента к непредназначенным для него данным. Кроме того, при использовании шаблона композиции API некоторые запросы могут привести к неэффективному объединению больших наборов данных в памяти. Поэтому для этого шаблона характерны проблемы с масштабируемостью и обслуживанием. Также такое архитектурное решение приводит к тесной связи между микросервисами, что считается антипаттерном. Сильная связность между микросервисами противоречит самой идее микросервисной архитектуры. В частности, при запросах к микросервисам необходимо знать структуру данных, возвращаемую запрашиваемыми микросервисами. Кроме того, усложняется реализация, поскольку требуется дополнительная логика для агрегирования и объединения данных из нескольких микросервисов. Композиция API может привести к дополнительным потерям производительности, поскольку микросервису оркестратора нужно дождаться ответов от нескольких микросервисов, прежде чем возвращать результат клиенту. При этом не получиться обеспечить обновление данных из нескольких микросервисов в режиме реального времени. Если данные в запрошенных микросервисах часто изменяются, композиция API может не отражать самые последние данные, что чревато снижением качества данных и устаревшеми сведениями в результатах запроса. Альтернативой является использование материализованных представлений и CDC-подход, что мы рассмотрим далее.

Изменим архитектуру проектируемой системы, используя захват измененных данных (CDC, Change Data Capture) и материализованные представления для оптимизации запросов к микросервисам в режиме реального времени и повышения производительности.

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

Как фиксировать изменения данных – через триггеры на таблицах БД, опросы, логи или готовые решения типа Debezium. Триггеры, как частный случай хранимых процедур, могут использоваться для выполнения действия при определенных событиях. Подробнее о сходстве и различии триггеров и хранимых процедур мы писали здесь на примере Greenplum. Опрос регулярно запрашивает базу данных, чтобы узнать, были ли внесены изменения. Логи фиксируют всю активность базы данных, включая изменения, и могут использоваться для обработки в реальном времени. Каждый из подходов имеет свои достоинства и недостатки, которые следует учитывать для каждого конкретного сценария.
Как передавать изменения данных – синхронно или асинхронно. Синхронная связь полезна для кратковременных транзакций, а асинхронная связь идеальна для длительных процессов.
Как обеспечить согласованность данных между сервисами – через использование распределенных транзакций, что чревато проблемами с производительностью, или через согласованность в конечном счете, когда каждый сервис работает со своими собственными данными и в конечном итоге становится согласованным с другими приложениями.

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

CDC позволяет реализовать инкрементные обновления хранилища данных, фиксируя изменения, внесенные в системе-источнике, чтобы загружать только их в DWH. Это сокращает время, необходимое для полной загрузки, и обеспечивает постоянную актуальность данных в хранилище данных. Также CDC можно использовать для потоковой передачи данных из нескольких источников с целью их анализа в реальном времени. Наконец, CDC пригодится для обновления моделей AI/ML новыми данными. CDC фиксирует изменения, внесенные в исходную базу данных, и обновляет модели AI/ML новыми данными. Это помогает обновлять ML-модели с использованием самых последних данных, повышая их точность.

Впрочем, помимо CDC-подхода в рассматриваемом кейсе интернет-магазина имеет смысл использовать и другой паттерн управления данными в микросервисной архитектуре – CQRS, суть которого в отделении запросов от команд. CQRS предполагает наличие базы данных представления, которая является доступной только для чтения репликой, предназначенной для поддержки запросов. Приложение поддерживает реплику в актуальном состоянии, подписываясь на события домена, публикуемые сервисом, которому принадлежат данные. Этот шаблон поддерживает несколько денормализованных представлений, которые являются масштабируемыми и производительными. Он позволяет упростить модели команд и запросов, что полезно в EDA-архитектуре, управляемой событиями в реальном времени.

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

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

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

Сперва идентифицируем запросы, требующие доступа к данным интернет-магазина в режиме реального времени, например, списки недавно просмотренных товаров. Основная цель здесь — сохранить данные, требуемые службой запросов, в денормализованном формате, чтобы обеспечить быстрый поиск. Материализованные представления денормализованы и оптимизированы для конкретного запроса или представления в пользовательском интерфейсе, чтобы быстрее и эффективнее извлекать данные. Материализованные представления могут быть созданы с использованием баз данных или специализированных систем кэширования. Чтобы получать обновления в режиме реального времени и поддерживать согласованность этих данных, подписавшись на изменения состояния баз других микросервисов, целесообразно использовать потоковую СУБД, например, Rockset, Materialise, RisingWave и DeltaStream. Подробнее о потоковых базах данных, которые поддерживают аналитические операции с непрерывными потоками данных в реальном времени с помощью SQL-запросов, мы писали здесь и здесь.

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

Возвращаясь к паттерну CQRS, который предполагает разделение команд и запросов, следует добавить микросервис, который будет обслуживать запросы на чтение, поступающие из пользовательского интерфейса клиентского приложения. Эти запросы API преобразуются в SQL-запросы, которые извлекают данные из материализованных представлений потоковой базы. Например, когда пользователь ищет товар, результаты поиска можно получить из материализованного представления для списков поиска, вместо того чтобы выполнять несколько вызовов API к различным микросервисам.

Таким образом, материализованные представления упрощают логику запросов, заранее агрегируя данные, избавляя разработчика от работы со сложными SQL-запросами со множеством JOIN-операторов. Благодаря оптимизации материализованных представлений под конкретные запросы, можно снизить нагрузку на основную базу данных и повысить общую производительность системы. Материализованные представления в потоковой базе данных могут предоставлять данные в режиме реального времени из нескольких микросервисов, реализуя шаблон CQRS. Разделение операций чтения и записи с предварительным вычислением представления данных также обеспечивает масштабируемость и отказоустойчивость. Потоковая база может быть развернута независимо от основной, что соответствует горизонтальному масштабированию запросов. Наконец, базу данных потоковой передачи можно использовать в качестве резерва на случай, если основная база выйдет из строя.
Обмен данными микросервисов с потоковой базой данных можно реализовать с помощью паттерна Outbox. Он обеспечивает асинхронный и децентрализованный обмен данными между микросервисами.

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

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

Также для обмена данными микросервисов с потоковой базой данных можно использовать платформу потоковой обработки событий, например, Apache Kafka. Она позволяет публиковать и подписываться на потоки событий, отказоустойчиво хранить и обрабатывать их в реальном времени.
Я не претендую на особую экспертизу в этом вопросе, но сомневаюсь, что внедрение service mech окупится из-за перечисленных вами фич. Зато если вы хотите пойти в Canary Deployment, то (скажем, совместно с Argo Rollouts), можно получить реальный profit.

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

А вот если бы вы поделились с общественностью деталями «словили кучу проблем с ним», было бы здорово.
А есть хоть какая-нибудь оценка того, сколько реально позволило сэкономить применение Istio? Желательно не на «сферическом примере в вакууме», а на реальном. Мы вот заморочились, внедрили Istio по требованиям организации, словили кучу проблем с ним. И никто не видит никакой пользы. Терминирование TLS особо не нужно (безопасность требует шифровать всё); балансировки по кругу хватает; размыкатели цепи в теории штука неплохая, но нередко уже встроена в библиотеки, да и без зашкаливающей нагрузки особо не нужна; метрики — и так всё обвешено Прометеями настолько, что глаз смотреть не хватает.
Istio — это service mesh с открытым кодом, который прозрачно накладывается на существующие распределённые приложения. Istio предлагает единообразный и эффективный подход к безопасности, взаимодействию и мониторингу.

Control plane в Istio реализована в контейнере Istiod, а data plane развёртывается в поде как sidecar с помощью контейнера с Envoy.

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

Прокси Envoy развёртываются как sidecar’ы в подах и дают несколько возможностей:

— динамическое обнаружение сервисов;

— балансировки нагрузки;

— терминация TLS;

— прокси HTTP/2 и gRPC;

— размыкатели цепи;

— проверки работоспособности;

— постепенное развёртывание с процентным разделением трафика;

— внесение ошибок;

— всевозможные метрики.

Если мы установим Istio в Kubernetes и создадим под, контейнер Envoy будет внедрен в него автоматически — его не придётся объявлять в манифесте пода. Сейчас Istio — это проект Cloud Native Computing Foundation (CNCF).Теперь вы знаете, зачем микросервисам нужна service mesh и причём тут Istio.
Когда мы создаём сервис Service B, сервер API Kubernetes уведомляет kube-proxy на рабочей ноде, чтобы он добавил в iptables правила для Service B. Когда какой-то под будет вызывать Service B, запрос сначала будет направлен в iptables. iptables заменит целевой IP в Packet X на IP пода Pod B и перешлёт запрос в Pod B.
Но у kube-proxy есть ограничения:

Запросы подам отправляются случайным образом.

Трафик нельзя поделить на части по процентам.

Канареечные и сине-зелёные развёртывания не поддерживаются.

Сложно мониторить и отлаживать.

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

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

У service mesh есть control plane управления и data plane. Первая управляет прокси для маршрутизации трафика, а вторая отвечает за коммуникации между сервисами. Data plane обычно реализуется как sidecar, который развёртывается вместе с кодом приложения.В Kubernetes data plane — это sidecar-контейнер рядом с главным контейнером в поде. Когда service mesh запускается на платформе кубернетес, data plane service mesh представлен sidecar-контейнером, который выполняется рядом с основным контейнером в поде. Эти sidecar-контейнеры обеспечивают взаимодействие между сервисами в разных подах. Таким образом теперь взаимодействие между подами происходит не через kube-proxy, а через sidecar: под обращается к sidecar-контейнеру и уже через него общается с другими подами.

Безопасность, автоматические повторы запросов, мониторинг и другие возможности обрабатывает sidecar-контейнер, а приложение содержит только бизнес-логику.Две самых популярных реализации service mesh — Istio и Consul. Мы познакомимся только с Istio.
Развёртывать микросервисы на сервере — то ещё удовольствие, даже с Kubernetes. К тому же Kubernetes не занимается коммуникациями между сервисами. Для этой задачи мы привлекаем Istio — реализацию service mesh.

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

Kubernetes использует интерфейс CNI для взаимодействия между сетью и подами в кластере. На рабочей ноде за общение подов отвечает kube-proxy — сетевой прокси, который работает на каждой ноде в кластере и управляет сетевыми правилами. Сетевые правила регулируют взаимодействие в кластере и за его пределами.

Когда мы создаём под, или сервис, kube-proxy обновляет правила iptables, чтобы поды могли общаться:
Это выглядит сложно, т. к. гит довольно весело ведёт себя с пустыми ветками и мне приходится делать дополнительные действия. На практике это на 90% «пуш в хелперы», «пул в проекте», «мёрдж хелперов в проект».
Это выглядит сложно, т. к. гит довольно весело ведёт себя с пустыми ветками и мне приходится делать дополнительные действия. На практике это на 90% «пуш в хелперы», «пул в проекте», «мёрдж хелперов в проект».
Cпасибо, но я думал это можно сделать проще
git может такое.

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

Поскольку git по природе своей распределённый, я сэмулирую ваш порядок работы в одном локальном репозитории на нескольких несвязанных ветках: a, b и master. Изменения в этих ветках могут запросто появляться из других репозториев (разные ветки могут следить за разными серверами!), но при использовании такой методики у вас локально должен быть репозиторий, в котором есть все три.
Поехали по пунктам:

Положим, что git init вы сделали, а С (сам проект) лежит в ветке master (что совершенно необязательно).

создать хранилище, где будут разные файлы скриптов (например, A)

Делаем «несвязанную ветку»:

git checkout --orphan a


Зачищаем папку и индекс, чтобы начать с чистого листа:

git reset && git clean -f


Делаем коммит с фигнёй:

echo 'скрипт' | tee script_a_1 script_a_2
git add .
git commit # Тут вас попросят ввести сообщение для коммита


хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B)

То же самое.

git checkout --orphan b
git reset && git clean -f
echo 'скрипт' | tee script_b_1 script_b_2
git add .
git commit # Сообщение для коммита


Когда я создаю новый проект — создается новое хранилище (например, C).

Будем считать, что это ветка master. И в настоящий момент она должна быть пуста, для git это означает, что она не существует, поэтому придётся делать её заново:

git checkout --orphan master
git reset && git clean -f


Теперь мне нужно в С перенести стандартный набор с хранилища В.

Мёрдж:

git merge b


При этом произойдёт fast-forward до b, master будет совпадать с веткой b. Это нормально. Ведь на этом этапе состояния файловой системы проекта совпадают, верно?

Потом мне нужно с А перенести 2 скрипта в С.

Мёрдж с a, но на сей раз с «тормозами», чтобы прямо перед коммитом git остановился:

git merge --no-commit --no-ff a


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

git reset script_a_2
git clean -f
git commit


Теперь немного «поработаем», для вида:

echo work > work
git add work
git commit


в стандартных файлах (которые хранятся в В) есть ошибка. Я ей исправляю и хочу залить как на В…

Поскольку у вас (семантически) master основан на b, а не наоборот, ошибку вам надо починить именно в b, чтобы потом изменения «растеклись» (не автоматически!) по тем, кто ею пользуется. Идём в ветку b и чиним:

git checkout b # clean уже не нужен, т. к. ветка не пустая
echo script > script_b_1 # Ну, допустим, что кириллица не переварилась. Мало ли.
git add script_b_1
git commit


На этом этапе, если репозитории с b и master всё-таки разные, должен быть git push ветки b в соответствующий репозиторий, а в репозитории проекта нужно сделать git pull --ff-only (--ff-only разрешает только перемотку ветки — чтобы ваши изменения не «затекли» в b) в ветке, которая за тем репозиторием следит. Это уже отдельная тема, если интересно, расскажу и об этом.

… так и на С.

Переходим в ветку с проектом:

git checkout master


И делаем мердж ветки b в проект.

git merge b


Готово. Да, вот так просто!

После проделывания вышеописанных манипуляций, я получил в master следующую схему из коммитов (git log --graph):

*   commit 2e9219cb2922f70382a8f069fdc917bdbfccd4b8
|\  Merge: 2cc463a 1fc0b61
| | Author: Имя <адрес>
| | Date:   Sun Dec 27 14:46:12 2015 +0300
| | 
| |     мердж фикса
| |   
| * commit 1fc0b61c1017acf4b4ef1941e1cdcb01a7e86be4
| | Author: Имя <адрес>
| | Date:   Sun Dec 27 14:41:23 2015 +0300
| | 
| |     фикс основы
| |   
* | commit 2cc463ae97500bff4a304990aa4e42159da96fe9
| | Author: Имя <адрес>
| | Date:   Sun Dec 27 14:38:37 2015 +0300
| | 
| |     работа
| |     
* |   commit cfa122c954f77b3282f51511f94bc6d97c95d569
|\ \  Merge: 7da066c f9304d8
| |/  Author: Имя <адрес>
|/|   Date:   Sun Dec 27 14:31:20 2015 +0300
| |   
| |       мердж с удалением лишних
| |   
| * commit f9304d82d89600add270544bec32cd6661a8c150
|   Author: Имя <адрес>
|   Date:   Sun Dec 27 13:46:39 2015 +0300
|   
|       скриптики
|  
* commit 7da066c234216057ff19775a355342ed501fe9a4
  Author: Имя <адрес>
  Date:   Sun Dec 27 13:54:01 2015 +0300
 
      основа

И для наглядности, перерисовал:
01:03 (отредактировано)
+1
git может такое.

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

Поскольку git по природе своей распределённый, я сэмулирую ваш порядок работы в одном локальном репозитории на нескольких несвязанных ветках: a, b и master. Изменения в этих ветках могут запросто появляться из других репозториев (разные ветки могут следить за разными серверами!), но при использовании такой методики у вас локально должен быть репозиторий, в котором есть все три.
Поехали по пунктам:

Положим, что git init вы сделали, а С (сам проект) лежит в ветке master (что совершенно необязательно).

создать хранилище, где будут разные файлы скриптов (например, A)

Делаем «несвязанную ветку»:

git checkout --orphan a


Зачищаем папку и индекс, чтобы начать с чистого листа:

git reset && git clean -f


Делаем коммит с фигнёй:

echo 'скрипт' | tee script_a_1 script_a_2
git add .
git commit # Тут вас попросят ввести сообщение для коммита


хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B)

То же самое.

git checkout --orphan b
git reset && git clean -f
echo 'скрипт' | tee script_b_1 script_b_2
git add .
git commit # Сообщение для коммита


Когда я создаю новый проект — создается новое хранилище (например, C).

Будем считать, что это ветка master. И в настоящий момент она должна быть пуста, для git это означает, что она не существует, поэтому придётся делать её заново:

git checkout --orphan master
git reset && git clean -f


Теперь мне нужно в С перенести стандартный набор с хранилища В.

Мёрдж:

git merge b


При этом произойдёт fast-forward до b, master будет совпадать с веткой b. Это нормально. Ведь на этом этапе состояния файловой системы проекта совпадают, верно?

Потом мне нужно с А перенести 2 скрипта в С.

Мёрдж с a, но на сей раз с «тормозами», чтобы прямо перед коммитом git остановился:

git merge --no-commit --no-ff a


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

git reset script_a_2
git clean -f
git commit


Теперь немного «поработаем», для вида:

echo work > work
git add work
git commit


в стандартных файлах (которые хранятся в В) есть ошибка. Я ей исправляю и хочу залить как на В…

Поскольку у вас (семантически) master основан на b, а не наоборот, ошибку вам надо починить именно в b, чтобы потом изменения «растеклись» (не автоматически!) по тем, кто ею пользуется. Идём в ветку b и чиним:

git checkout b # clean уже не нужен, т. к. ветка не пустая
echo script > script_b_1 # Ну, допустим, что кириллица не переварилась. Мало ли.
git add script_b_1
git commit


На этом этапе, если репозитории с b и master всё-таки разные, должен быть git push ветки b в соответствующий репозиторий, а в репозитории проекта нужно сделать git pull --ff-only (--ff-only разрешает только перемотку ветки — чтобы ваши изменения не «затекли» в b) в ветке, которая за тем репозиторием следит. Это уже отдельная тема, если интересно, расскажу и об этом.

… так и на С.

Переходим в ветку с проектом:

git checkout master


И делаем мердж ветки b в проект.

git merge b


Готово. Да, вот так просто!

После проделывания вышеописанных манипуляций, я получил в master следующую схему из коммитов (git log --graph):

*   commit 2e9219cb2922f70382a8f069fdc917bdbfccd4b8
|\  Merge: 2cc463a 1fc0b61
| | Author: Имя <адрес>
| | Date:   Sun Dec 27 14:46:12 2015 +0300
| | 
| |     мердж фикса
| |   
| * commit 1fc0b61c1017acf4b4ef1941e1cdcb01a7e86be4
| | Author: Имя <адрес>
| | Date:   Sun Dec 27 14:41:23 2015 +0300
| | 
| |     фикс основы
| |   
* | commit 2cc463ae97500bff4a304990aa4e42159da96fe9
| | Author: Имя <адрес>
| | Date:   Sun Dec 27 14:38:37 2015 +0300
| | 
| |     работа
| |     
* |   commit cfa122c954f77b3282f51511f94bc6d97c95d569
|\ \  Merge: 7da066c f9304d8
| |/  Author: Имя <адрес>
|/|   Date:   Sun Dec 27 14:31:20 2015 +0300
| |   
| |       мердж с удалением лишних
| |   
| * commit f9304d82d89600add270544bec32cd6661a8c150
|   Author: Имя <адрес>
|   Date:   Sun Dec 27 13:46:39 2015 +0300
|   
|       скриптики
|  
* commit 7da066c234216057ff19775a355342ed501fe9a4
  Author: Имя <адрес>
  Date:   Sun Dec 27 13:54:01 2015 +0300
 
      основа

И для наглядности, перерисовал:
Как организовать работу с системами контроля версий для разработки нескольких проектов с общей основой?

Стоит следующая задача: мне надо создать хранилище, где будут разные файлы скриптов (например, A). Также будет хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B). Когда я создаю новый проект — создается новое хранилище (например, C).

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

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

В какой системе контроля версий и каким образом можно организовать хранилища для решения этой задачи?
Как организовать работу с системами контроля версий для разработки нескольких проектов с общей основой?

Стоит следующая задача: мне надо создать хранилище, где будут разные файлы скриптов (например, A). Также будет хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B). Когда я создаю новый проект — создается новое хранилище (например, C).

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

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

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

Заявка на услуги DST

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

Адрес

Ижевск, ул. Воткинское шоссе 170 Е.
Региональный оператор Сколково. Технопарк Нобель

8 495 1985800
Заказать звонок

Режим работы: Пн-Пт 10:00-19:00

info@dstglobal.ru

Задать вопрос по почте

Укажите ваше имя
Укажите ваше email
Укажите ваше телефон