Для тех, кто работает с огромными наборами данных (от гигабайтов до терабайтов), BigMemory — продукт, который стоит рассмотреть, поскольку он позволяет вашему java-приложению обрабатывать большие объемы данных в памяти. Это означает, что вы получаете быстрый доступ к вашим данным.
Версия 4.0 вышла через несколько дней, давайте посмотрим, что внутри.
1) «Быстрый доступ к данным в терабайтном масштабе»
Есть интересная статья, которая была опубликована в прошлом году. Это сообщает о результатах масштабирования тестового приложения. Размер набора данных начинался с 2 ГБ и доходил до 1,8 ТБ. Пропускная способность оставалась в пределах приблизительно 10% от среднего значения без скачков задержки, вызванных сборкой мусора. В целом, скорость чтения / записи в BigMemory примерно одинакова: от гигабайтов до терабайтов данных.
Архитектура следующая:
Каждый экземпляр вашего приложения использует Ehcache для кэширования набора данных в куче. Затем вы определяете в Ehcache нужный вам размер магазина BigMemory. Эта часть называется offheap, так как это память, которая не обрабатывается сборщиком мусора (таким образом, это не куча)
Вы можете реплицировать свой кеш / хранилище BigMemory среди нескольких экземпляров вашего приложения, подключив их к серверу Terracotta. Обратите внимание, что сервер Terracotta также может использовать BigMemory для хранения дополнительных данных.
С точки зрения разработки, если вы знакомы с Ehcache, вы не будете потеряны.
Создание экземпляра Bigmemory будет выглядеть так:
import net.sf.ehcache.*; import net.sf.ehcache.config.*; Configuration cfg = new Configuration() .terracotta(new TerracottaClientConfiguration().url("localhost:9510")) .cache(new CacheConfiguration().name("myDataTableExample") .maxBytesLocalHeap(1, MemoryUnit.GIGABYTES) .maxBytesLocalOffHeap(4, MemoryUnit.GIGABYTES) .terracotta(new TerracottaConfiguration()) ); CacheManager manager = CacheManager.newInstance(cfg); Ehcache myDataTableExample = manager.getEhcache("myDataTableExample"); String key = "some key"; SomeCustomEntity value = .... SomeCustomEntity newValue = .... myDataTableExample.put(new Element(key, value)); myDataTableExample.replace(new Element(key, newValue)); value = (SomeCustomEntity)myDataTableExample.get(key).getObjectValue(); myDataTableExample.remove(key); manager.shutdown();
2) «Мониторинг»
Это относится к инструменту мониторинга под названием TMC.
После установки архива BigMemory вы сможете запустить его из командной строки с помощью одного из следующих сценариев, в зависимости от используемой версии:
tools/management-console/bin/start-tmc.sh
или же
management-console/bin/start-tmc.sh
Тогда приложение мониторинга можно открыть в вашем браузере на
http://localhost:9889/tmc
В этом примере хранилище кластеризовано (совместно используется различными JVM) через сервер Terracotta, а консоль мониторинга получает информацию с сервера Terracotta.
Это означает, что в случае, если вы находитесь в автономном режиме (хранилище работает в одной JVM), вы не используете сервер Terracotta. Вам необходимо указать в своей конфигурации, что вы собираетесь публиковать свои данные в консоли мониторинга:
ManagementRESTServiceConfiguration restCfg = new ManagementRESTServiceConfiguration(); restCfg.setSecurityServiceLocation("http://localhost:9889/tmc/api/assertIdentity"); Configuration cfg = new Configuration() .managementRESTService(restCfg) .cache(new CacheConfiguration().name("myDataTableExample") .maxBytesLocalHeap(1, MemoryUnit.GIGABYTES) .maxBytesLocalOffHeap(4, MemoryUnit.GIGABYTES) );
3) «Быстрый перезапуск для аварийного восстановления»
Теперь все становится еще интереснее. Не только все данные находятся в памяти, но они могут быть сохранены на диске, поэтому в случае сбоя или после перезапуска приложения данные загружаются обратно в память.
Есть 4 варианта, но я сосредоточусь на двух самых важных: localRestartable и распределенный
a) localRestartable используется для автономной конфигурации, сохраняя данные на диск
Configuration cfg = new Configuration() .diskStore(new DiskStoreConfiguration().path("/mydisk/mystore/")) .cache(new CacheConfiguration().name("myPersistentDataTableExample") .maxBytesLocalHeap(1, MemoryUnit.GIGABYTES) .maxBytesLocalOffHeap(4, MemoryUnit.GIGABYTES) .persistence(new PersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.LOCALRESTARTABLE)) );
б) распределенный используется для кластерной конфигурации, сохраняя данные на сервере терракоты, который будет отвечать за сохранение их на диске
Configuration cfg = new Configuration() .diskStore(new DiskStoreConfiguration().path("/mydisk/mystore/")) .terracotta(new TerracottaClientConfiguration().url("localhost:9510")) .cache(new CacheConfiguration().name("myPersistentDataTableExample") .maxBytesLocalHeap(1, MemoryUnit.GIGABYTES) .maxBytesLocalOffHeap(4, MemoryUnit.GIGABYTES) .terracotta(new TerracottaConfiguration()) .persistence(new PersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.DISTRIBUTED)) );
И добавьте в конфигурацию сервера терракоты (tc-config.xml):
<restartable enabled="true"/> <offheap> <enabled>true</enabled> <maxDataSize>....</maxDataSize> </offheap>
4) «Поддержка поиска»
Как мы уже видели, с BigMemory у нас есть хранилище данных <Key, Value> в памяти, которое можно кластеризовать и сохранить на диске.
Поскольку цель состоит в том, чтобы хранить как можно больше данных в памяти и по-прежнему обеспечивать удобный доступ к данным, мы также имеем Поддержка запросов, аналогично тому, что вы найдете в базе данных.
Для описания всех функций поддержки поиска потребуется целый пост, поэтому приведу простой пример:
Скажем, мы помещаем в память экземпляры класса Person, которые будут иметь эти два поля:
private String familyName; private Integer age;
Найти каждого человека с фамилией, начинающейся с ‘A’, будет:
import net.sf.ehcache.search.*; import net.sf.ehcache.search.aggregator.*; Query query = myPersistentDataTableExample.createQuery() .addCriteria(new ILike("familyName", "A%")) .includeValues() .addOrderBy(new Criteria("familyName"), Direction.ASCENDING); Results results = query.execute(); List<Result> all = results.all(); for (Result result : all) { Person person = (Person)result.getValue(); }
5) «Hadoop Ready»
Это еще один интересный функционал.
Если вы не очень знакомы с Hadoop, это система, которая позволяет обрабатывать большие наборы данных.
Он очень мощный, потому что вы можете использовать обычные серверы, а Hadoop позаботится о распределении работы между ними.
Hadoop имеет собственную файловую систему с именем HDFS, и вам сначала необходимо импортировать данные в систему HDFS, прежде чем их можно будет обработать.
Однако вы не можете получить результаты в реальном времени, так как вам нужно подождать, пока весь процесс будет выполнен, прежде чем вы сможете получить доступ к данным в HDFS.
Появляются некоторые решения, такие как запросы Cloudera Impala в реальном времени.
BigMemory решает проблему, предоставляя разъем Hadoop. С помощью этого соединителя Hadoop может отправлять данные в BigMemory, как только они обрабатываются, делая их доступными для памяти в режиме реального времени.
В Hadoop интерфейсы OutputFormat и RecordWriter определяют, как обрабатываются выходные данные сопоставления / сокращения заданий.
Например, по умолчанию TextOutputFormat помещает данные в файл в системе HDFS.
Вместо этого вы можете использовать EhcacheOutputFormat, то есть пользовательскую реализацию OutputFormat, которая будет записывать данные в BigMemory.
Если мы возьмем известный пример Hadoop Wordcount,
public static void main(String[] args) throws Exception { JobConf conf = new JobConf(WordCount.class); conf.setJobName("wordcount"); conf.setOutputKeyClass(Text.class); conf.setOutputValueClass(IntWritable.class); conf.setMapperClass(Map.class); conf.setCombinerClass(Reduce.class); conf.setReducerClass(Reduce.class); conf.setInputFormat(TextInputFormat.class); conf.setOutputFormat(TextOutputFormat.class); FileInputFormat.setInputPaths(conf, new Path(args[0])); FileOutputFormat.setOutputPath(conf, new Path(args[1])); JobClient.runJob(conf); }
это превратится в
public static void main(String[] args) throws Exception { JobConf conf = new JobConf(WordCount.class); conf.setJobName("wordcount"); conf.setOutputKeyClass(Text.class); conf.setOutputValueClass(EhcacheElementWritable.class); conf.setMapperClass(Map.class); conf.setCombinerClass(Reduce.class); conf.setReducerClass(Reduce.class); conf.setInputFormat(TextInputFormat.class); conf.setOutputFormatClass(EhcacheOutputFormat.class); // FileInputFormat.setInputPaths(conf, new Path(args[0])); JobClient.runJob(conf); }
Вам также необходимо определить конфигурацию ehcache.xml (в соответствии с форматом ehcache).
Затем в вашем приложении вы сможете инициализировать его как стандартный ehcache и получать данные, как только они будут в памяти.
6) Еще …
Под капотом есть другие вещи.
Библиотека инструментов доступна для кластерных объектов (таких как коллекции, блокировки, синхронизация …).
Функциональность безопасности была улучшена. Как и в версии 3.7, связь на основе SSL доступна для безопасной настройки. Кроме того, вы можете использовать сервер LDAP или Active Directory для хранения учетных данных.
А также, Java 7 поддерживается …
Так что, если вы заинтересованы в мире больших данных, вы обязательно должны проверить это здесь.
Не стесняйтесь оставлять комментарии, если вам нужно больше точности!