Zkybase — это моя первая попытка создания базы данных управления конфигурацией с открытым исходным кодом (CMDB), но я не впервые создаю CMDB. На работе группа из нас создала и продолжает создавать собственную внутреннюю систему CMDB, называемую deathBURRITO, в рамках наших усилий по автоматизации развертывания. Мы создали deathBURRITO, используя Java, Spring, Hibernate и MySQL. У deathBURRITO даже есть роботизированный осел (на самом деле), цель которого мы еще не определили.
Пока смерть BURRITO хорошо сработала для нас. Некоторые из его функций, а именно те, которые непосредственно поддерживают автоматизацию развертывания, оказались более полезными, чем другие. Но общее согласие, по-видимому, заключается в том, что deathBURRITO устраняет важный пробел в управлении конфигурацией (CM), когда ранее мы «управляли» данными CM в вики отдела, в электронных таблицах, в файлах XML и на диаграммах Visio. Хотя впереди еще много работы, то, что мы сделали до сих пор, было достаточно правильным, и мы смогли развить его по мере развития наших потребностей.
Это не значит, что я бы ничего не изменил. Я думаю, что есть возможность сделать что-то лучше на бэкэнде. Это действительно был стимул для Zkybase.
Пересмотр бэкэнда с Spring Data
Поскольку CM включает в себя множество различных типов объектов (например, регионы, центры обработки данных, среды, фермы, типы экземпляров, образы машин, экземпляры, приложения, промежуточное программное обеспечение, пакеты, развертывания, группы безопасности EC2, пары ключей — список можно продолжить и на), было полезно создать небольшую структуру для более или менее автоматической обработки различных сквозных задач, таких как стандартные представления (представление списка, представление сведений, представления формы), веб-контроллеры (операции CRUD, стандартные запросы), DAO (опять же, операции и запросы CRUD), общие возможности объекта домена, безопасность и многое другое. И я думаю, будет справедливо сказать, что это помогло, хотя, возможно, не так сильно, как мне бы хотелось (по крайней мере, пока). Факт остается фактом, что каждый раз, когда мы хотим добавить новый объект в систему,нам все еще нужно проделать немалую работу, чтобы каждый слой фреймворка делал то, что должен.
По моему опыту, слой сохраняемости данных является наиболее сложным для изменения. Помимо фактических изменений схемы, мы должны написать сценарии переноса данных, мы должны внести соответствующие изменения в наши сценарии данных тестов интеграции, мы должны убедиться, что энергичная и ленивая загрузка Hibernate делают правильные вещи, иногда нам приходится менять API-интерфейсы объекта домена и связанные запросы Hibernate и т. д. Конечно, выполнимо, но обычно требуется много планирования, обсуждения и тестирования.
Поэтому я начал искать способы упростить бэкэнд.
Недавно я начал бездельничать с Spring Data , в частности Spring Data JPA и Spring Data MongoDB . Для тех, кто не использовал Spring Data, он предлагает несколько приятных функций, которые я хотел бы попробовать:
- Одна из особенностей заключается в том, что он может генерировать реализации DAO автоматически, используя механизм динамического прокси Java. Spring Data называет эти DAO «репозиториями», что меня устраивает. В основном, как разработчик, вы пишете интерфейс, расширяющий интерфейс репозитория для конкретного типа, например JpaRepository или MongoRepository. Вам не нужно объявлять операции CRUD, потому что интерфейс Repository уже объявляет те, которые вы обычно хотите (например, save (), findAll (), findById (), delete (), deleteAll (), exist (), count) (), и т.д.).
- А если у вас есть пользовательские запросы, просто объявите их в интерфейсе, используя некоторые соглашения об именах методов, и Spring Data сможет выяснить, как создать реализацию для вас.
- В некоторых случаях Spring Data обрабатывает сопоставление для вас. В случае Spring Data JPA вы все равно должны убедиться, что у вас есть правильные аннотации JPA, и это не так уж плохо. Но для MongoDB, поскольку бэкэнд MongoDB — это просто BSON (двоичный JSON), сопоставление объектов с MongoDB является простым, поэтому Spring Data справляется с этим очень хорошо, не требуя множества аннотаций.
«Изменитель игры» может быть слишком сильным для функций, которые я только что описал, но, черт возьми, они полезны. Помимо упрощения и ускорения реализации репозиториев, Spring Data позволяет мне избавиться от большого количества стандартного кода (множества реализаций DAO) и даже от некоторого кода среды DAO, подобного Spring Data, который я обычно пишу. (Вы знаете, определите общий интерфейс DAO, общий абстрактный класс DAO и т. Д.) Мои дни создания DAO непосредственно против Hibernate, вероятно, прошли.
Но это не единственное изменение бэкенда, на которое я смотрю.
Пересмотр бэкэнда, часть 2: Neo4j + Spring Data Neo4j
Поскольку Spring Data имеет тенденцию тяготеть к хранилищам NoSQL, я наконец-то нашел время для чтения Neo4j и некоторых других вещей, о которых мне, вероятно, следовало бы прочитать давно. Лучше поздно, чем никогда, я думаю. Меня поразило, что Neo4j может быть очень интересным способом реализации бэкэнда CM, и что Spring Data Neo4j может помочь мне сохранить уровень DAO тонким. Вот мысли:
- Есть много сущностей и отношений. В CMDB есть множество сущностей и отношений. Существуют различные способы группировки вещей, такие как группировка ресурсов, которые образуют стек, какие стеки для развертывания, какие экземпляры, какие экземпляры в каких фермах, как определить сегменты и как определять отказоустойчивые фермы, группировать функции в приложения, конечные точки в службы и т. д. Мы должны связать SLA и OLA с функциями приложений и конечными точками служб, мы должны определить зависимости между компонентами и так далее. Там масса вещей. Это исключило бы основную часть работы, если бы мы могли избежать определения схемы один раз (скажем, в самом приложении), а не в приложении и базе данных.
- Нам нужна гибкость схемы, чтобы экспериментировать с различными подходами CMDB. В том же духе существуют сильные силы, которые подталкивают гибкость схемы. В сущности, правильный подход к разработке и внедрению CMDB не обязательно является решаемой проблемой. Некоторые инструменты включают запуск агентов сетевого обнаружения, которые собирают миллионы элементов конфигурации (CI) из среды. Другие инструменты сосредоточиться на сборе праводанные, а не собирать все. Некоторые инструменты имеют в виду больше традиционных клиентов центра обработки данных, где вы собираете все, начиная с чистого листа и заканчивая приложениями и службами ITIL на основе этих приложений. Другие инструменты более согласованы с облачными инфраструктурами, начиная с виртуализированной инфраструктуры и заканчивая работой, оставляя все на этом уровне виртуализации для беспокойства поставщика облачных вычислений. Некоторые инструменты рассматривают CI как поддерживающие управление конфигурацией, но не управление производительностью приложений (APM); другие инструменты пытаются получить данные CM и APM из одного источника. Некоторые организации хотят централизовать CI в единой базе данных, а другие организации используют более федеративную модель. При таком разнообразии подходов неудивительно, что происходят изменения схемы.
- Нам нужна гибкость схемы, чтобы учесть постоянные инновации в инфраструктуре. Другой движущей силой схемы является тот факт, что способ, которым мы работаем с инфраструктурой, быстро развивается. Инфраструктура постоянно перемещается в облако, виртуализация является обычным явлением, и постоянно появляются новые инструменты автоматизации и мониторинга. Постоянный поток инноваций требует способности быстро приспосабливаться, и гибкость схемы — большая часть этого.
- Нам нужна гибкость схемы для удовлетворения потребностей различных организаций. Помимо гибкости схемы, CMDB должен предлагать определенный уровень гибкости для удовлетворения потребностей различных клиентов. У одной организации может быть все в облаке, а другая только намокает. Одна организация может иметь две среды, тогда как другая имеет семь. Различные организации имеют разные роли, процессы тестирования, конвейеры развертывания и так далее. Любая CMDB, которая надеется поддерживать больше, чем просто один клиент, должна поддерживать некоторый уровень гибкости.
- Но нам все еще нужна структура. Одним из наиболее мощных преимуществ автоматизации развертывания с помощью CMDB является то, что вы можете контролировать дрейф в целевых средах, управляя данными в своей CMDB. И определение схемы вокруг этого — отличный способ сделать это. Если, например, вы ожидаете, что каждый экземпляр в данной ферме будет иметь одну и ту же ОС, тогда ваша схема должна подключать ОС к самой ферме, а не к экземпляру. (Экземпляры наследуют ОС от фермы.) Или, может быть, это не просто ОС — вам нужен определенный тип экземпляра (с точки зрения профиля виртуального оборудования), определенного образа машины, определенного стека промежуточного программного обеспечения, определенной конфигурации безопасности и т. Д. Отлично: объедините их в один объект сборки сервера, а затем свяжите это с фермой. Это ограничивает экземпляры в ферме для одинаковой сборки сервера. (Увидетьэтот пост для более подробного обсуждения.) Хотя в Neo4j нет схемы, Spring Data Neo4j дает нам возможность навязывать схему из уровня приложения.
- Бэкэнд без схемы упрощает развертывание без простоев. Если у вас есть какие-либо приложения с жесткими требованиями к доступности, то само собой разумеется, что для их поддержки необходима значительная автоматизация как на стороне развертывания, так и на стороне реагирования на инциденты. Поскольку CMDB является единственным источником правды, управляющим этой автоматизацией, из этого следует, что сама CMDB должна иметь жесткие требования к доступности. Наличие базы данных без схемы должно упростить развертывание самой CMDB без простоев.
- Мы хотим поддерживать интуитивные запросы. Как только вы соберете несколько CI в CMDB, появятся всевозможные запросы. Это может быть что угодно — от использования структуры зависимостей для диагностики инцидента, оценки влияния изменений или последовательности результатов проекта (например, обеспечение высокой доступности компонентов системы в зависимости от того, где они находятся на графике зависимостей системы); использование структур org для определения путей эскалации поддержки и горизонтальных каналов связи; SLA отчетность по группам, менеджерам, категориям приложений; и так далее. Интуитивно понятные языки запросов для баз данных графов — и, в частности, язык запросов Cypher для Neo4j — особенно хорошо подходят для широкого спектра запросов, которые мы ожидаем увидеть.
Помните, как я упоминал, что Spring Data генерирует реализации репозитория автоматически на основе интерфейсов? Вот как это выглядит с Spring Data Neo4j:
package org.skydingo.zkybase.repository; import org.skydingo.zkybase.model.Person; import org.skydingo.zkybase.model.Project; import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.neo4j.repository.GraphRepository; public interface ProjectRepository extends GraphRepository<Project> { Project findProjectByKey(String key); Project findProjectByName(String name); @Query("start person=node({0}) match person-->project return project") Iterable<Project> findProjectsByPerson(Person person); }
Let me repeat that I don’t have to write the repository implementation myself. GraphRepository comes with various CRUD operations. Methods like findProjectByKey() and findProjectByName() obey a naming convention that allows Spring Data to produce the backing query automatically. And in the findProjectsByPerson() case, I provided a query using Neo4j’s Cypher query language (it uses ASCII art to define queries–how ridiculously cool is that?).
Exploring the ideas above with Zkybase
The point of Zkybase is to see whether we can build a better mousetrap based on the ideas above. I’m using Neo4j and Spring Data Neo4j to build it out. I haven’t decided yet whether Zkybase will focus on the CMDB piece or whether it’s a frontend to configuration management more generally (delegating on the backend to something like Chef or Puppet, say), but the CMDB will certainly be in there. That will include a representation of the as-is (current) configuration as well as representations for desired configurations as might be defined during a deployment planning activity.
So far I’m finding it a lot easier to work with the graph database than with a relational database, and I’m finding Spring Data Neo4j to be a big help in terms of repository building and defining app-level schemas. The code is a lot smaller than it was when I did this with a relational database. But it’s still early days, so the jury is out.
Watch this space for further developments.