Недавно вышла новая версия распределённой SQL базы данных Apache Ignite, предлагаю взглянуть на новые фичи с позиции .NET.


Ignite Cluster


Thin .NET Client


До версии 2.4 как в Java, так и в .NET, было два варианта подключения к кластеру: Server и Client. В целом, клиентский режим отличается от серверного только тем, что клиентские узлы не хранят данные и не выполняют вычисления (compute, map-reduce). В остальном переиспользуются существующие компоненты discovery & communitaction. Присоединение клиентского узла к кластеру — относительно тяжёлый процесс, который может занять несколько секунд.


Ситуация с .NET осложняется тем, что внутри процесса стартует JVM, потребляя немало ресурсов и внося дополнительные требования к окружению.


Все эти проблемы решает наш новый «тонкий» клиент:


  • Подключается к одному из серверных узлов через сокет, мгновенный процесс.
  • Не требует наличия Java на машине, не запускает JVM.
  • Практически не потребляет памяти.
  • Подключается к любым типам узлов Ignite: Java-only, .NET, C++.

Из функциональности есть пока только Cache + LINQ, в будущем планируется добавить всё остальное.
При этом API выглядит идентично:


var cfg = new IgniteClientConfiguration { Host = "127.0.0.1" };
using (var client = Ignition.StartClient(cfg))
{
    var cache = client.GetCache<int, Person>("persons");
    cache[1] = new Person(1, "Vasya");
    cache[2] = new Person(2, "Petya");

    // SQL
    cache.Query(new SqlFieldsQuery("select name from person where id > 1"));

    // LINQ
    cache.AsCacheQueryable().Where(x => x.Value.Id > 1) ...;
}

Надо заметить, что появление тонкого клиента вовсе не означает, что существующий "толстый" API будет в будущем отправлен на свалку:


  • Скорость работы тонкого клиента всегда будет чуть ниже, так как он работает через посредника.
  • Многие фичи, такие как Compute и Services, работают на серверных нодах через "толстый" API (даже если вызваны со стороны клиента).

Пример в LINQPad
В процессе работы с Ignite может возникнуть желание быстро подключиться к кластеру, посмотреть на данные в кэшах, запустить какой-то запрос. Для этого существуют такие инструменты, как Visor Command Line и Web Console.


С появлением тонкого клиента всё это можно быстро и удобно делать через LINQPad. Достаточно добавить NuGet пакет Apache.Ignite через "Add NuGet...", и готовый пример кода будет загружен автоматически.


Скриншот

Ignite.NET Thin Client LINQPad Sample


.NET Core, Mono, Linux, macOS


Ignite.NET in Visual Studio Code on macOS


Заголовок говорит сам за себя, теперь Ignite.NET можно использовать на следующих платформах и ОС:


  • Windows (.NET 4.0+, .NET Core 2.0+, Mono)
  • Linux (любой дистрибутив, где работает .NET Core 2.0+ или Mono)
  • macOS (опять же под .NET Core 2.0+ или Mono)

Как попробовать?
Под .NET Core инструкция одинаковая для всех платформ:


  • dotnet new console
  • dotnet add package Apache.Ignite
  • В Program.cs добавляем Apache.Ignite.Core.Ignition.Start();
  • dotnet run

warning NU1701: This package may not be fully compatible with your project.

Сборка проекта выдаст предупреждение warning NU1701: Package 'Apache.Ignite 2.4.0' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.0'. This package may not be fully compatible with your project.


Причина в том, что внутри NuGet пакета лежит единственная dll-ка, собранная под .NET 4.0, что сделано для упрощения процесса. Это нисколько не мешает ей работать под .NET Core. Подавить предупреждение можно при помощи строчки <PropertyGroup><NoWarn>NU1701</NoWarn></PropertyGroup>в файле csproj.


Mono
Mono работает с обычными 'Classic .NET' солюшнами, создать их на Linux можно в MonoDevelop.


Один из юз кейсов для Mono — это 32-битные процессоры, ведь .NET Core требует x64. Я столкнулся с этим, тестируя запуск Ignite.NET на всём, что попадало под руку, а под руку попался старенький EEE PC 901 с установленной Lubuntu, где под Mono всё благополучно запустилось.


Разработка на Linux и macOS
Помимо использования, Ignite.NET теперь также можно и разрабатывать на Linux и macOS. Под Mono основной солюшн компилируется как есть. Под .NET Core для этого добавлены отдельные файлы солюшна и проектов под .NET Core:
Apache.Ignite.DotNetCore.sln.


Заключение


Ignite.NET теперь охватывает все основные платформы и операционные системы. Один из востребованных use cases, ставший возможным, это кластер из .NET узлов, запущенный на Linux, и клиентские приложения, работающие через «тонкий» протокол на рабочих станциях под Windows.


Планируется дальнейшее развитие направления .NET Core: интеграция с ASP.NET Core (кэширование) и Entity Framework Core (кэширование, провайдер данных). Такие интеграции уже существуют для классических ASP.NET и EF.

Комментарии (8)


  1. Hixon10
    27.03.2018 00:52
    +1

    Извините, я немного не в теме C#, но

    Ситуация с .NET осложняется тем, что внутри процесса стартует JVM, потребляя немало ресурсов и внося дополнительные требования к окружению.


    Скорость работы тонкого клиента всегда будет чуть ниже, так как он работает через посредника.


    Это как? О какой тут скорости идёт речь? Тонкий клиент медленнее из-за сетевого взаимодействия? А как толстый клиент с JVM обшается? Это быстро?


    1. kefirr Автор
      27.03.2018 01:08

      Представим узлы кластера А и Б, толстый клиент К, тонкий клиент Т подключен к узлу А.


      При попытке извлечь данные, находящиеся на узле Б, толстый клиент отправит запрос напрямую. Тонкий же работает только через узел А.


      А как толстый клиент с JVM обшается? Это быстро?

      Через JNI и указатели на unmanaged (offheap) память. Да, это намного быстрее сокета.


      1. Hixon10
        27.03.2018 01:10

        Спасибо!


  1. mayorovp
    27.03.2018 07:53

    А нельзя ли «толстую» версию клиента через IKVM запустить? Насколько это будет стабильно и быстро?

    У меня уже был опыт использования JMS через IKVM — работало нормально.


    1. kefirr Автор
      27.03.2018 10:36

      Ради прикола попробовать можно было бы, но для продакшна это точно не решение.
      Да и проект IKVM загнулся, к сожалению.
      http://weblog.ikvm.net/2017/04/21/TheEndOfIKVMNET.aspx


    1. devozerov
      27.03.2018 10:43
      +1

      Добавлю, что типичный оверхед на JNI составляет несколько десятков наносекунд. Reverse JNI на момент замеров (JDK 7) был немного медленнее, чем прямой. В рамках распределенной системы, где типичный latency измеряется миллисекундами, оверхед JNI амортизируется практически в ноль.


      1. mayorovp
        27.03.2018 17:18

        Меня больше волнует не оверхед на JNI — а дополнительные требования к окружению.


        1. kefirr Автор
          27.03.2018 17:32

          Именно поэтому сделан тонкий клиент, который использует только чистый .NET и дополнительных требований не имеет.