Инструкции и рекомендации для надежных коллекций в Azure Service Fabric
В этом разделе приведены инструкции по использованию надежных коллекций и диспетчера надежных состояний. Цель этого руководства — помочь пользователям избежать распространенных ошибок.
Инструкции составлены как простые рекомендации со словами Делайте, Постарайтесь, Избегайте и Не делайте в начале.
- Не изменяйте объекты пользовательского типа, возвращаемые операциями чтения (например, TryPeekAsync или TryGetValueAsync ). Надежные коллекции, как и параллельные коллекции, возвращают ссылку на объект, а не его копию.
- Обязательно создайте глубокую копию возвращенного объекта пользовательского типа, прежде чем изменять этот объект. Поскольку структуры и встроенные типы передаются по значению, вам необязательно создавать их глубокую копию, если они не содержат поля или свойства со ссылками, которые вы собираетесь изменить.
- Не используйте TimeSpan.MaxValue для времени ожидания. Время ожидания следует использовать для выявления взаимоблокировок.
- Не используйте транзакцию после того, как она была зафиксирована, прервана или удалена.
- Не используйте перечисление за пределами области транзакции, в которой оно было создано.
- Не создавайте транзакцию в операторе using другой транзакции, так как это может привести к взаимоблокировке.
- Не создавайте надежное состояние с помощью IReliableStateManager.GetOrAddAsync и используйте надежное состояние в одной транзакции. Это приведет к исключению InvalidOperationException.
- Убедитесь, что реализация IComparable<TKey> правильна. Система использует соответствующую зависимость IComparable<TKey> для слияния контрольных точек и строк.
- Используете блокировку изменения при чтении элемента с целью обновить его, чтобы предотвратить взаимоблокировки определенного класса.
- Рекомендуем использовать менее 1000 надежных коллекций на раздел. Лучше использовать большее количество элементов в надежных коллекциях, чем большее количество надежных коллекций с меньшим количеством элементов.
- Постарайтесь поддерживать размер элементов (например, TKey + TValue для надежного словаря) до 80 КБ: чем меньше, тем лучше. Это позволит уменьшить объем использования кучи больших объектов, а также снизить требования к дискам и сетевым операциям ввода-вывода. Часто это также помогает уменьшить репликацию повторяющихся данных при обновлении только небольшой части значения. Распространенный способ добиться этого в надежном словаре — разбить строки на несколько строк.
- Возможно, вас заинтересует применение функций архивации и восстановления для аварийного восстановления.
- Избегайте совместного использования операций с одной сущностью и операций с несколькими сущностями (например, GetCountAsync , CreateEnumerableAsync ) в одной и той же транзакции ввиду различных уровней изоляции.
- Обработайте исключение InvalidOperationException. Пользовательские транзакции могут быть прерваны системой по разным причинам. Например, если диспетчер надежных состояний изменяет свою роль с основной на какую-то другую, или когда транзакция с длительным временем выполнения блокирует усечение журнала транзакций. В таких случаях пользователь может получить исключение InvalidOperationException, указывающее на то, что его транзакция уже завершена. Если предположить, что завершение транзакции не было запрошено пользователем, то лучший способ обработки этого исключения — удалить транзакцию и проверить, не получен ли сигнал в виде токена отмены (или изменена роль реплики). И если нет, то создать новую транзакцию и повторить попытку.
При этом нужно помнить о следующем:
- Время ожидания по умолчанию составляет четыре секунды для всех API надежных коллекций. Большинство пользователей должны использовать время ожидания по умолчанию.
- Во всех API надежных коллекций токеном отмены по умолчанию является CancellationToken.None .
- Параметр типа ключа (TKey) для надежного словаря должен правильно реализовывать и Equals() . Ключи должны быть неизменяемыми.
- Чтобы обеспечить высокую доступность надежных коллекций, в каждой службе необходимый и минимальный размер набора реплик должен быть равен как минимум 3.
- Операции чтения в базе данных-получателе могут считывать версии без кворума. Это означает, что версия данных, считываемая из отдельной базы данных-получателя, может быть ложно увеличена. Чтение из базы данных-источника всегда стабильно и не может вызывать ложное увеличение номера версии.
- Безопасность и конфиденциальность данных, хранимых приложением в надежной коллекции, зависит от вашего решения и средств, предоставляемых управлением хранилищем. Например, можно использовать шифрование дисков операционной системы для защиты неактивных данных.
- Перечисление ReliableDictionary использует отсортированную структуру данных, упорядоченную по ключу. Чтобы сделать перечисление эффективным, фиксации добавляются во временную хэш-таблицу и затем перемещаются в основную отсортированную структуру данных после контрольной точки. Операции добавления, обновления и удаления имеют лучшее время выполнения O(1) и худшее время выполнения O(log n) в случае проверки наличия ключа. Операции Get могут иметь сложность O(1) или O(log n) в зависимости от того, выполняется ли чтение из последней фиксации или из более старой фиксации.
Непостоянные надежные коллекции
При принятии решения о работе с непостоянными надежными коллекциями учитывайте следующее: