Поделиться через


ADO.NET сохраняемость зерна

Серверный код Orleans реляционного хранилища основан на универсальных ADO.NET функциональных возможностях и, следовательно, не зависит от поставщика базы данных. Макет Orleans хранилища данных уже описан в таблицах среды выполнения. Настройка строка подключения выполняется, как описано в Orleans руководстве по настройке.

Чтобы создать Orleans функцию кода с заданной серверной частью реляционной базы данных, необходимо следующее:

  1. Соответствующая ADO.NET библиотека должна быть загружена в процесс. Это должно быть определено как обычно, например с помощью элемента DbProviderFactories в конфигурации приложения.
  2. Настройте ADO.NET инвариант через Invariant свойство в параметрах.
  3. База данных должна существовать и быть совместима с кодом. Это делается путем запуска сценария создания базы данных для конкретного поставщика. Дополнительные сведения см. в разделе ADO.NET Конфигурация.

Поставщик хранилища зерна ADO .NET позволяет хранить состояние зерна в реляционных базах данных. В настоящее время поддерживаются следующие базы данных:

  • SQL Server
  • MySQL/MariaDB
  • PostgreSQL
  • Oracle

Сначала установите базовый пакет:

Install-Package Microsoft.Orleans.Persistence.AdoNet

Ознакомьтесь со статьей о конфигурации ADO.NET для получения сведений о настройке базы данных, включая соответствующие ADO.NET инвариантные и скрипты установки.

Ниже приведен пример настройки поставщика хранилища ADO.NET с помощью ISiloHostBuilder:

var siloHostBuilder = new HostBuilder()
    .UseOrleans(c =>
    {
        c.AddAdoNetGrainStorage("OrleansStorage", options =>
        {
            options.Invariant = "<Invariant>";
            options.ConnectionString = "<ConnectionString>";
            options.UseJsonFormat = true;
        });
    });

По сути, необходимо задать только строка подключения для конкретной базы данных и Invariant конфигурацию (см. ADO.NET конфигурацию), которая идентифицирует поставщика. Вы также можете выбрать формат, в котором сохраняются данные, которые могут быть двоичными (по умолчанию), JSON или XML. Хотя двоичный файл является самым компактным, он непрозрачн, и вы не сможете читать или работать с данными. Json — это рекомендуемый вариант.

С помощью AdoNetGrainStorageOptionsследующих свойств можно задать следующие свойства:

/// <summary>
/// Options for AdoNetGrainStorage
/// </summary>
public class AdoNetGrainStorageOptions
{
    /// <summary>
    /// Define the property of the connection string
    /// for AdoNet storage.
    /// </summary>
    [Redact]
    public string ConnectionString { get; set; }

    /// <summary>
    /// Set the stage of the silo lifecycle where storage should
    /// be initialized.  Storage must be initialized prior to use.
    /// </summary>
    public int InitStage { get; set; } = DEFAULT_INIT_STAGE;
    /// <summary>
    /// Default init stage in silo lifecycle.
    /// </summary>
    public const int DEFAULT_INIT_STAGE =
        ServiceLifecycleStage.ApplicationServices;

    /// <summary>
    /// The default ADO.NET invariant will be used for
    /// storage if none is given.
    /// </summary>
    public const string DEFAULT_ADONET_INVARIANT =
        AdoNetInvariants.InvariantNameSqlServer;

    /// <summary>
    /// Define the invariant name for storage.
    /// </summary>
    public string Invariant { get; set; } =
        DEFAULT_ADONET_INVARIANT;

    /// <summary>
    /// Determine whether the storage string payload should be formatted in JSON.
    /// <remarks>If neither <see cref="UseJsonFormat"/> nor <see cref="UseXmlFormat"/> is set to true, then BinaryFormatSerializer will be configured to format the storage string payload.</remarks>
    /// </summary>
    public bool UseJsonFormat { get; set; }
    public bool UseFullAssemblyNames { get; set; }
    public bool IndentJson { get; set; }
    public TypeNameHandling? TypeNameHandling { get; set; }

    public Action<JsonSerializerSettings> ConfigureJsonSerializerSettings { get; set; }

    /// <summary>
    /// Determine whether storage string payload should be formatted in Xml.
    /// <remarks>If neither <see cref="UseJsonFormat"/> nor <see cref="UseXmlFormat"/> is set to true, then BinaryFormatSerializer will be configured to format storage string payload.</remarks>
    /// </summary>
    public bool UseXmlFormat { get; set; }
}

ADO.NET сохраняемость имеет функциональные возможности для данных версии и определяют произвольные сериализаторы (de)сериализаторы с произвольными правилами приложения и потоковой передачей, но в настоящее время нет метода предоставления его коду приложения.

ADO.NET обоснование сохраняемости

Принципы ADO.NET резервного хранилища сохраняемости:

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

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

Помимо обычных возможностей поставщика хранилища, поставщик ADO.NET имеет встроенные возможности:

  1. Изменение данных хранилища с одного формата на другой (например, из JSON в двоичный) при циклического обхода.
  2. Создайте тип для сохранения или чтения из хранилища произвольными способами. Это позволяет развиваться версии состояния.
  3. Потоковая передача данных из базы данных.

Оба 1. и 2. могут применяться на основе произвольных параметров принятия решений, таких как идентификатор зерна, тип зерна, данные полезных данных.

Это так, чтобы можно было выбрать формат сериализации, например простую двоичную кодировку (SBE) и реализующую IStorageDeserializer и IStorageSerializer. Встроенные сериализаторы созданы с помощью этого метода:

После реализации сериализаторов их необходимо добавить в StorageSerializationPicker AdoNetGrainStorageсвойство. Ниже приведена реализация IStorageSerializationPicker. По умолчанию будет использоваться StorageSerializationPicker. Пример изменения формата хранилища данных или использования сериализаторов можно увидеть в Relational служба хранилища Tests.

В настоящее время нет метода предоставления средства выбора Orleans сериализации приложению, так как нет метода для доступа к созданной AdoNetGrainStorageплатформе.

Цели проектирования

1. Разрешить использование любой серверной части с поставщиком ADO.NET

Это должно охватывать наиболее широкий набор серверных компонентов, доступных для .NET, что является фактором в локальных установках. Некоторые поставщики перечислены в ADO.NET обзоре, но не все они перечислены, например Teradata.

2. Сохраняйте потенциал для настройки запросов и структуры базы данных соответствующим образом, даже при выполнении развертывания

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

3. Вы можете использовать возможности для конкретных поставщиков и версий.

Поставщики реализовали различные расширения и функции в своих продуктах. Это разумно использовать эти функции, когда они доступны. Это такие функции, как собственный UPSERT или PipelineDB в PostgreSQL, PolyBase или собственные скомпилированные таблицы и хранимые процедуры в SQL Server.

4. Оптимизация аппаратных ресурсов

При разработке приложения часто можно предвидеть, какие данные необходимо вставить быстрее, чем другие данные, и какие данные могут быть помещены в холодное хранилище, что дешевле (например, разделение данных между SSD и HDD). Дополнительные рекомендации включают физическое расположение данных (некоторые данные могут быть более дорогими (например, SSD RAID viz HDD RAID), или более защищенными) или некоторыми другими основами принятия решений. Связанные с точкой 3., некоторые базы данных предлагают специальные схемы секционирования, такие как секционированные таблицы и индексы SQL Server.

Эти принципы применяются в течение жизненного цикла приложения. Учитывая, что одним из принципов Orleans является высокий уровень доступности, необходимо настроить систему хранения без прерывания Orleans развертывания или настроить запросы в соответствии с данными и другими параметрами приложения. Пример динамических изменений можно увидеть в блоге Брайана Гарри:

Если таблица небольшая, это почти не имеет значения, что такое план запроса. Когда это средний, план запросов ОК хорошо, но когда это огромный (миллионы на миллионы или миллиарды строк), даже небольшой вариант плана запроса может убить вас. По этой причине мы намекаем на наши конфиденциальные запросы.

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

Многие организации знакомы с определенным набором средств базы данных, примерами которых является Dacpac или Red Gate. Это может быть то, что для развертывания базы данных требуется разрешение или пользователь, например кто-то в роли DBA. Как правило, это означает также наличие макета целевой базы данных и грубого эскиза запросов, которые приложение будет производить для использования при оценке нагрузки. Могут возникнуть процессы, возможно, влияют на отраслевые стандарты, которые определяют развертывание на основе скриптов. Наличие запросов и структур баз данных во внешнем скрипте делает это возможным.

6. Используйте минимальный набор функций интерфейса, необходимых для загрузки библиотек и функций ADO.NET

Это быстро и имеет меньше поверхности, подверженной несоответствиям реализации библиотеки ADO.NET.

7. Сделать макет сегментируемым

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

8. Сделать дизайн простым для тестирования

Создание серверной части в идеале должно быть таким же простым, как перевод одного из существующих скриптов развертывания на диалект SQL серверной части, которую вы пытаетесь нацелить, добавив новый строка подключения к тестам (предполагая параметры по умолчанию), проверка, чтобы узнать, установлена ли определенная база данных, а затем выполните тесты с ним.

9. Учитывая предыдущие моменты, сделайте перенос скриптов для новых серверных и изменение уже развернутых скриптов серверной части как можно более прозрачным.

Реализация целей

Платформа Orleans не знает о оборудовании для конкретного развертывания (которое оборудование может изменяться во время активного развертывания), изменение данных во время жизненного цикла развертывания или некоторые функции, относящиеся к поставщику, которые доступны только в определенных ситуациях. По этой причине интерфейс между базой данных и Orleans должен соответствовать минимальному набору абстракций и правил для удовлетворения этих целей, сделать его надежным в отношении неправильного использования и упростить проверку при необходимости. Таблицы среды выполнения, управление кластерами и конкретная реализация протокола членства. Кроме того, реализация SQL Server содержит настройку выпуска SQL Server. Контракт интерфейса между базой данных и Orleans определяется следующим образом:

  1. Общая идея заключается в том, что данные считываются и записываются с помощью Orleansконкретных запросов. Orleans работает с именами столбцов и типами при чтении, а также именах и типах параметров при записи.
  2. Реализации должны сохранять входные и выходные имена и типы. Orleans использует эти параметры для чтения результатов запроса по имени и типу. Разрешена настройка для конкретного поставщика и конкретного развертывания, и при сохранении контракта интерфейса рекомендуется внести взносы.
  3. Реализация в сценариях , относящихся к поставщику, должна сохранять имена ограничений. Это упрощает устранение неполадок в соответствии с универсальным именованием в конкретных реализациях.
  4. Версия (или ETag в коде приложения) — для Orleansэтого представляет уникальную версию. Тип фактической реализации не важен, если он представляет уникальную версию. В реализации Orleans код ожидает 32-разрядное целое число со знаком.
  5. Для того чтобы быть явным и удалять неоднозначность, ожидается, Orleans что некоторые запросы возвращают значение TRUE в виде значения 0 или FALSE как > = 0. То есть количество затронутых или возвращенных строк не имеет значения. Если возникает ошибка или возникает исключение, запрос должен обеспечить откат всей транзакции и возвратить значение FALSE или распространить исключение.
  6. В настоящее время все, кроме одного запроса, являются однострочные вставки или обновления (обратите внимание, что запросы INSERTможно заменить UPDATE на , если связанные SELECT запросы выполнили последнюю запись).

Ядра СУБД поддерживают программирование в базе данных. Это похоже на идею загрузки исполняемого скрипта и вызова его для выполнения операций базы данных. В псевдокоде его можно представить следующим образом:

const int Param1 = 1;
const DateTime Param2 = DateTime.UtcNow;
const string queryFromOrleansQueryTableWithSomeKey =
    "SELECT column1, column2 "+
    "FROM <some Orleans table> " +
    "WHERE column1 = @param1 " +
    "AND column2 = @param2;";
TExpected queryResult =
    SpecificQuery12InOrleans<TExpected>(query, Param1, Param2);

Эти принципы также включаются в скрипты базы данных.

Некоторые идеи по применению настраиваемых скриптов

  1. Измените скрипты OrleansQuery для сохраняемости зерна таким IF ELSE образом, чтобы некоторые состояния сохранялись с помощью значения по умолчанию INSERT, в то время как некоторые состояния зерна могут использовать оптимизированные для памяти таблицы. Запросы SELECT необходимо изменить соответствующим образом.
  2. Идея 1. может использоваться для использования других аспектов развертывания или поставщиков, таких как разделение данных между SSD или HDDразмещение некоторых данных в зашифрованных таблицах или, возможно, вставка статистических данных через SQL-Server-to-Hadoop или даже связанных серверов.

Измененные скрипты можно протестировать, выполнив Orleans набор тестов или прямо в базе данных, используя, например, проект модульного тестирования SQL Server.

Рекомендации по добавлению новых поставщиков ADO.NET

  1. Добавьте новый скрипт настройки базы данных в соответствии с разделом "Реализация целей " выше.
  2. Добавьте инвариантное имя поставщика ADO и ADO.NET данные, относящиеся к AdoNetInvariants поставщику, в DbConstantsStore. Они (потенциально) используются в некоторых операциях запроса. Например, чтобы выбрать правильный режим вставки статистики (т. е UNION ALL . с или без FROM DUAL).
  3. Orleans имеет комплексные тесты для всех системных хранилищ: членство, напоминания и статистика. Добавление тестов для нового скрипта базы данных выполняется путем копирования существующих тестовых классов и изменения инвариантного имени ADO. Кроме того, наследуйте реляционную служба хранилища ForTesting, чтобы определить функциональные возможности тестирования для инвариантной ADO.