Технология ухода от баз данных в программировании
Инженер Антон Чижов о преимуществах оперативной памяти, способах хранения данных и системе «Апрентис»
В конце 2007 года я запускал проект, это был некоторый стартап, в котором мы хотели сделать достаточно гибкую облачную систему создания бизнес-приложений. Это была новая идея работы с облаками, которые тогда активно развивались, веб-система, позволявшая создавать полноценные бизнес-приложения для малого и среднего бизнеса, для фирм, которые разбросаны по территории, то есть им трудно работать с общим сервером, нет выделенных каналов, и потому проще использовать интернет.
У нас тогда был опыт работы с Salesforce — к тому моменту это самая крупная облачная система в Соединенных Штатах, много сотен тысяч одновременно работающих пользователей. Но было понимание, что так просто Salesforce в Россию не придет, и хотелось сделать что-то собственное, что позволяло бы делать похожего рода приложения, и сделать из этого бизнес, как-то раскрываться, расширяться. Но было очевидно, что нужны новые идеи того, как это может быть сделано, как это может быть реализовано. И в основу этой системы — потом она получила название «Апрентис» — был положен подход, который тогда был трендом, и постепенно он завоевывает все больше и больше признания и в наше время, хотя прошло уже достаточно много лет. Этот подход связан с уходом от баз данных.
В компьютерах практически с самого начала их появления появилось разделение на оперативную память, то есть те данные, которые для программы доступны непосредственно и с которыми программа работает как со своими данными, и на внешнюю память — на дисках, когда-то на лентах, сейчас на жестких дисках, в наше время это уже SSD-диски, дальше будут еще какие-то технологии, в какой-то момент были CD-диски, DVD, и это все внешняя информация, которая на самом деле для процессора, для компьютера, для самой инфраструктуры требует специальных усилий, для того чтобы получить в свою обработку.
Так как эти данные всегда имеют большее время доступа — то есть, чтобы их получить, нужно существенно больше времени, чем просто залезть в оперативную память и вытащить конкретное значение, — то возникали различные варианты ускорения или организации доступа к этим данным. Один из таких способов — это база данных. База данных позволяет, если говорить кратко, быстро добираться, обновлять данные на основе каких-то фильтров, каких-то способов сортировки, то есть заказывая последовательность выборки данных определенным способом, причем очень разным. Базы данных как направление развивались в течение очень многих лет, оно основано на некоторых математических подходах, на реляционной алгебре, и это сильно развитая, очень продуманная дисциплина программирования.
С развитием компьютеров оказалось, что в них можно использовать довольно много оперативной памяти. И для какого-то количества задач проблема разделения данных на те, которые непосредственно доступны компьютеру, то есть в оперативной памяти, и те, которые находятся чуть подальше, то есть в базе данных, начала уходить на второй план. Когда мы начинали работать с этой системой, уже были некоторые системы, которые назывались memcached, то есть в оперативной памяти тем или иным образом кешировалась, создавалась копия данных из базы данных, и программа фактически работала с этой копией.
Мы же попробовали пойти немножко дальше, ведь памяти в компьютере на самом деле становилось много, то есть в те времена, в 2007 году, можно было думать о гигабайте-другом оперативной памяти, в 2014 году совершенно естественно и легко получить сервер, в котором 128 гигабайт оперативной памяти. И задач, которые помещают все свои данные в эти десятки гигабайтов оперативной памяти, становится все больше и больше, в том плане, что те задачи, которые требуют работы с памятью, все больше и больше могут работать просто с оперативной памятью. Конечно же, есть понятие Big Data, есть задачи, которые в это дело не влезают, но тут каждой задаче нужно предлагать свой подход, эффективный в наше время и с нашими ресурсами.
Мы попробовали сделать такую систему, которая бы держала все данные в оперативной памяти.
Но, в отличие от memcached, мы подумали, что правильно было бы пойти путем, когда система сама себя настраивает на структуру данных, и вообще не думать о настройке базы данных на структуру данных, требуемых по конкретному приложению. Тем самым мы получаем очень большую гибкость, а база данных используется только для персистирования, то есть для хранения данных в то время, когда, скажем, компьютер выключен, или для того, чтобы не потерять данные в принципе.
В отличие от memcached-вариантов тот подход, который мы использовали, то есть прямая компиляция структуры данных в соответствующие классы, структуру и тому подобное, позволяет очень легко и удобно работать со связями между объектами, между данными — она позволяет значительно более объектно подойти с точки зрения объектного программирования к процессу обработки данных, а также существенно повышает скорость работы. Любые системы типа memcached либо NoSQL (есть такое понятие — NoSQL баз данных), которые тоже используют хранение информации в оперативной памяти, все-таки основаны на каких-то динамически создаваемых кортежах, тем самым в том или ином виде интерпретации информации, с которой надо работать. То есть, вытаскивая информацию из NoSQL базы, мапированной на оперативную память, все-таки нужно разобраться, какие данные в ней есть.
В нашем же подходе, с одной стороны, получилась несколько более жесткая структура информации, потому что мы должны объявить заранее, то есть это, что называется в программировании, строгая типизация. С другой стороны, к такому строго типизированному типу, у которого есть много плюсов, связанных с тем, что с данными можно работать непосредственно, не думая, а все-таки есть то или иное поле, есть те или иные данные в нем, можно прикреплять и слабо типизированные данные, тем самым работая и в режиме строгой типизации, и в режиме слабой типизации типа языков JavaScript или что-нибудь в этом роде.
Такая комбинация подходов требует гибкой динамичной перекомпиляции всех классов, которые хранят данные. Это некоторое усложнение всего подхода и всей этой системы, но усложнение не слишком серьезное, потому что в современных системах программирования, операционных системах или платформах типа .NET и Java такие средства для динамической перекомпиляции просто встроены в систему, это съедает небольшое количество процессорного времени для самого процесса перекомпиляции при изменении структуры данных, и это слабо заметно реальному пользователю.
Перенесение акцента хранения данных с баз данных в оперативную память приводит не только к увеличению скорости работы — оно приводит и к увеличению гибкости. Дело в том, что организация данных в виде сикульных, то есть на основе реляционной алгебры, на основе тех базовых подходов правильного доступа к данным, уход от этой модели, с одной стороны, позволяет использовать более гибкие структуры данных, такие, которые в сикульных базах просто невозможны, исходя из их некоторой математической природы, а с другой стороны, порождают проблемы оптимизации, потому что именно за счет математической основы, реляционной алгебры, основы сикульных вычислений и строятся способы оптимизации доступа к данным.
Хотя, конечно же, идей очень много, и они очень по-разному реализуются, каким же образом такую оптимизацию производить. Практически всегда такие оптимизации требуют некоторого усилия со стороны программиста, то есть он должен тем или иным образом указать, что ему хочется проводить оптимизацию. Такой же подход используется и в базах данных, потому что для того, чтобы все работало эффективно, надо построить индексы, тем самым указать, что именно хочется оптимизировать с точки зрения базы. Так и в нашем подходе приходится указывать, какие компоненты нужно правильным образом оптимизировать. Соответственно, так как все это работает на основе обычных классов, то есть объектный подход проявляется в полной степени, то достаточно легко добавлять к подобным системам разнообразные средства профилирования, оценки скорости, оценки того, где и как возникают основные задержки, тем самым подобного рода системы оказываются еще и гибкими с точки зрения их сопровождения и оптимизации.
Очень хотелось бы, чтобы подходы по такой жесткой типизации хранения данных в оперативной памяти в больших объемах в противоположность подходу того, что называется memcached, то есть относительно неструктурированному способу хранения данных, скорее, в виде мягких типов, получило больше распространения. Потому что об этом мало говорят, эти идеи достаточно слабо представлены в программистском сообществе, а, с моей точки зрения, за ними достаточно приличное будущее, особенно с учетом того, что объемы оперативной памяти становятся все больше и больше. И мы придем к тому, что для очень большого круга задач хранение данных на внешних носителях скоро станет совсем бессмысленно.
Антон Чижов
Полный текст статьи читайте на Postnauka.ru