Статьи

Как сделать сложный запрос в режиме реального времени на больших данных

Первоначально написано Рон Завнер.

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

Мы часто не понимаем, что здесь есть несколько проблем:

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

    Первый вызов — большие данные

    Теперь, если мы начнем с больших данных, есть много решений, которые мы можем использовать для решения этих проблем. Наиболее популярными решениями будут mongoDB, Cassandra и Hadoop. Все эти решения являются распределенными средами, которые имеют несколько разделов, содержащих наши данные. Они также реплицируют разделы, чтобы гарантировать, что мы можем обслуживать данные с другого компьютера, если один из компьютеров не работает (большинство из них в конечном итоге непротиворечивы, что означает, что реплика может не иметь самое последнее обновление данных, но это для другого обсуждения). Затем, если мы возьмем эти базы данных NoSQL, мы легко сможем решить эту проблему с помощью объема данных, а также проблемы с высокой доступностью. Это также масштабируемое решение, поскольку мы можем добавить больше вычислительных ресурсов и ресурсов хранения, что позволит поддерживать больше данных и пропускной способности.

    Второй вызов — в режиме реального времени

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

    Но и это решение не так просто. Мы можем хранить, возможно, несколько ТБ данных в ОЗУ, но что будет, если у нас будет больше? Скажем, 50 ТБ… хотя в наши дни ОЗУ намного дешевле, 50 ТБ будет очень дорого. Более того, это становится слишком большим количеством машин для управления в одном кластере сетки данных. Некоторые из решений IMDG предлагают способ сохранить некоторые данные в памяти, а некоторые — на диске (или в БД), но опять же мы сталкиваемся с той же проблемой медленного доступа ввода-вывода к диску, что приводит к «не очень реальному» запрос времени ».

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

  • Быстрый индексный режим — мы храним в inRAM поля, по которым мы запрашиваем, а остальные поля хранятся на SSD. Если, например, у нас есть большой объект со многими полями, мы можем хранить только несколько из них в RAM (проиндексированных) и менее важных полях на SSD, поэтому мы все равно можем очень быстро запрашивать их относительно обычного диска.
  • Последние использованные объекты — самые последние использованные объекты будут храниться в ОЗУ, а остальные будут перемещены в SSD. Этот подход все еще может иметь проблему реального времени, поскольку механизм запросов должен работать с SSD, а не с RAM для сложных вычислений, которые требуют всех данных.
    По сути, SSD позволяет нам наслаждаться обоими мирами — очень быстрым доступом к данным с использованием оперативной памяти для «важных» полей и расширением памяти, чтобы иметь реальную поддержку больших данных, которые мы не можем получить с помощью базовой IMDG.
  • Третий вызов — сложные запросы

    Мы по-прежнему остаемся со сложными частичными запросами — большинству приложений все еще нужна аналитика в реальном времени, которую в реляционных БД мы можем легко реализовать с помощью агрегации (avg, min, max, sum, group by и т. Д. В распределенных средах это это гораздо сложнее, поскольку данные распределены по кластеру, и агрегировать их означает — нам нужно либо передать все данные клиенту (не вариант, так как их слишком много), либо использовать карту сокращения логики. Использование логики сокращения карт — это нормально решение, но гораздо менее интуитивно, чем простой оператор SQL с группировкой.

    Потенциальное решение — XAP

    XAP — это сетка данных в памяти, предоставляемая Gigaspaces, которая может помочь решить все проблемы, указанные выше. В XAP версии 10 есть поддержка интеграции SSD, как указано выше, и сложных запросов. Он также предлагает высокую доступность, масштабируемость, поддержку транзакций, SQL-запросы (включая вложенные запросы).

    Let’s say we have a table of 100M employees which is too heavy too large a dataset for in memory and we want to run complex query in real time. We could store the employee IDs, department IDs, salary and age in RAM and the rest of the fields (address, notes, records, previous salaries etc in the SSD). The advantage of the SSD integration is that XAP really leverages the SSD power by working with its native API and storing the data as a key value store while other integrations are using SSD just as a fast disk. While when you use SSD just as a fast disk you do gain some performance impact, the performance impact is smaller than working with the SSD API because it still has to go through some hoops of a disk based solution. XAP would just store the object payload in the SSD using key value utilizing the API.
    Now we want to get the average, min and max salary grouped by department and sex type only for employees which are older than 50.
    In SQL it would look like:

    select AVG(salary), MIN(salary), MAX(salary) from Employees WHERE age > 50 group by Department, SexType

    In XAP it would look like:

    query = new SQLQuery(Person.class, “age > ?”, 50);
    groupByResult = groupBy(gigaSpace, query, new GroupByAggregator()
    .groupBy(“department”, “sexType”)
    .selectAverage(“salary”)
    .selectMinValue(“salary”)
    .selectMaxValue(“salary”));

    Summary
    To conclude, the need for real time complex querying on big data is out there. We can use SSD to store payload of objects while the indexes will be stored inRAM for ultra fast access – that is how we can combine a real in memory data grid with the native support for big data. The next challenge we need to face is how to run (intuitively) complex querying that work on nested fields or aggregations on that huge set of data. I showed a quick example here how it can be done with XAP and I’d be happy to see more examples if you can share.

    Originally written by Ron Zavner.