Статьи

Отрывок главы «Большие данные»: реализация схем с помощью Apache Thrift


Это отрывок из будущей книги Мэннинга о больших данных.

 

 Большие данные

Принципы и лучшие практики масштабируемых систем данных реального времени

Натан Марц и Сэмюэл Э. Ричи

Thrift — широко используемый проект, созданный на Facebook. Он может использоваться для создания RPC-серверов, не зависящих от языка, но разработчики используют его для создания возможностей схемы. В этой статье на основе главы 2Автор Натан Марц обсуждает рабочие лошадки Thrift — определения типа struct и union — и встроенные механизмы Thrift для развития схемы с течением времени.

 

Вы также можете быть заинтересованы в …

Thrift — широко используемый проект, созданный на Facebook. Он может использоваться для создания RPC-серверов, не зависящих от языка, но разработчики используют его для создания возможностей схемы. Рабочими лошадками Thrift являются определения типа struct и union , а Thrift имеет встроенные механизмы для развития схемы с течением времени.

Авторы: Натан Марц и Сэмюэл Э. Ричи.

Структуры

В следующем коде показано, как определить структуру с использованием языка определения интерфейса Thrift (IDL). Определение структуры похоже на определение класса на объектно-ориентированном языке: вы указываете все данные, которые содержит объект. Разница заключается в том, что структура Thrift содержит только данные и не определяет никакого дополнительного поведения для объекта. Поля в структуре могут быть:

  • Примитивные типы, такие как строки, целые, длинные и двойные. В Thrift IDL они называются string , i32 , i64 и double соответственно.
  • Коллекции других типов. Thrift поддерживает список , карту и набор .
  • Еще одна структура или союз.

struct Person {

  1: string twitter_username;

  2: string full_name;

  3: list<string> interests;

}

 

В следующем листинге кода показано, как сериализовать структуру с помощью Java. Как видите, мы используем ArrayList, нативную структуру данных Java, как часть объекта Person.

List<String> interests = new ArrayList<String>() {{

    add("hadoop");

    add("nosql");

}};
Person person = new Person("joesmith", "Joe Smith", interests);

TSerializer serializer = new TSerializer();

byte[] serialized = serializer.serialize(person);

Вот как десериализовать объект Person в Python. Когда объект десериализован, он будет использовать собственные структуры данных Python для любых типов коллекций.

person = Person()

deserialize(person, serialized_bytes)

Поля в структурах могут быть определены как
обязательные или
необязательные . Если поле определено как обязательное, тогда необходимо указать значение для этого поля, иначе Thrift выдаст ошибку при сериализации или десериализации. Если поле является необязательным, значение будет нулевым, если не указано иное. Вы должны всегда объявлять поля как обязательные или необязательные. В следующем листинге кода показано, как определить структуру, содержащую обязательные и дополнительные поля.

struct Tweet {

1: required string text;

2: required i64 id;

3: required i64 timestamp;

4: required Person person;

5: optional i64 response_to_tweet_id;

Союзы

Вы также можете определить союзы в Thrift. Объединение — это структура, которая должна иметь ровно один набор полей. Союзы полезны для представления полиморфных данных. В следующем листинге показано, как определить «PersonID», используя объединение Thrift, которое может быть одним из множества различных типов идентификаторов.

union PersonID {

  1: string email;

  2: i64 facebook_id;

  3: i64 twitter_id;

}

 

Эволюция схемы

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

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

Резюме

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

Существует несколько различных платформ сериализации с открытым исходным кодом, а именно Thrift, Protocol Buffers и Avro. Мы обсуждали наш любимый Apache Thrift, потому что он зрелый и поддерживает большинство языков, но вы можете использовать любой из этих инструментов для определения схемы.

 


Вот некоторые другие названия Мэннинга, которые могут вас заинтересовать:

 

MongoDB в действии

Кайл Банкир

RabbitMQ в действии

Альваро Видела и Джейсон Дж. Уильямс

Hadoop в действии

Чак Лэм

 

Последнее обновление: 11 января 2012 г.