• Привет, Гость!
  • Войти
  • Регистрация
  • Записи
  • Форумы
  • Люди
  • Файлы
  • Работа
  • Технологии
  • Все
  • Новости
  • События
  • Статьи
  • Блоги

Прогнозирование "тормозов" от включения прозрачного шифрования баз данных (TDE) в Microsoft SQL Server 2008

Прогнозирование "тормозов" от включения прозрачного шифрования баз данных (TDE) в Microsoft SQL Server 2008

yliberman
07.05.2008 6:56

Введение

Есть в Microsoft SQL Server 2008 такая новая штука как прозрачное шифрование баз данных, в оригинале Transparent Data Encryption (TDE). Включаем шифрование для базы данных, и все данные надежно защищены от некоторых напастей (кстати,  далеко не от всех). При этом менять существующие приложения не нужно. Я уже писал в своем блоге про эту новую возможность:

Ссылка: SQL Server 2008 Transparent Data Encryption (Прозрачное шифрование баз данных)

Там были рассмотрены следующие вопросы:

  • Основные принципы работы TDE
  • Иерархия ключей в TDE
  • Сценарии, в которых применение TDE имеет смысл с точки зрения повышения безопасности, а от каких угроз бесполезно защищаться с помощью TDE
  • Настройка TDE (включение TDE для базы данных)
  • Что именно шифруется?

Есть еще один интересный вопрос, который я намеренно вынес из того поста, так как хочу остановиться на нем подробнее. Этот вопрос: "Как включение TDE отразится на скорости работы приложения?". Вопрос производительности очень актуален в контексте TDE, так как значительные (а иногда очень значительные) дополнительные затраты на шифрование могут стать серьезным барьером на пути применения TDE в реальных проектах. Этому вопросу я решил посвятить сразу два поста - один с теорией, а другой с практикой. В теоретический части описываются нюансы реализации TDE в Microsoft SQL Server 2008, а также описана основанная на этих знаниях методика прогнозирования влияния TDE на производительность приложения. Практическая часть посвящена готовому решению для прогнозирования, которое реализует эту методику. Нельзя сказать, что теоретическая часть очень сложна, но, вспоминая озадаченность коллег, когда они видели на моем столе кучу исписанных формулами листков, я решил поменять части местами. В этом посте (в первом) на двух примерах рассматривается готовое решение для прогнозирования влияния TDE на производительность, а потом во второй части, я напишу как это все работает.

 

Решение для прогнозирования влияния TDE на производительность приложения

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

Процедуры прогнозирования влияния TDE на производительность приложения (TDE_Forecast_Procs.zip - 4,95 KB) 

Для чего предназначена каждая процедура описано в следующей таблице:

Процедура Описание
dbo.spu_CryptSymAlg_TestSpeed Определяет скорость шифрования и расшифровки для указанного симметричного алгоритма.
dbo.spu_CryptAsymAlg_TestSpeed Определяет скорость расшифровки для указанного асимметричного алгоритма.
dbo.spu_CryptAcquireContext_TestSpeed Определяет скорость выполнения CryptoAPI функции CryptAcquireContext.
dbo.spu_TDEForecast_SavePoint Сохраняет под указанным в параметре именем ряд текущих значений из различных источников (главным образом из системных динамических представлений), на основе которых потом считаются исходные данные для прогноза.
dbo.spu_TDEForecast_Result Основная процедура. Возвращает значения, определяющие загрузку сервера на исследуемом интервале времени (длительность интервала, потребление процессора, объем ввода/вывода и т.д.), и то, как эти значения изменятся после включения TDE.

Схема использования этих процедур для прогнозирования

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

  • dbo.spu_CryptSymAlg_TestSpeed - в параметре нужно указать имя алгоритма, которым планируется шифровать данные в базе данных (можно измерить производительность разных алгоритмов и разных длин ключей и посчитать на основе этих значений разные прогнозы).
  • dbo.spu_CryptAsymAlg_TestSpeed - в параметре нужно указать имя алгоритма, которым будет зашифрован Database Encryption Key (DEK). Напомню, что этот ключ шифруется сертификатом, который должен быть предварительно создан в базе данных master. В SQL сервере  поддерживается только один ассиметричный алгоритм - RSA, соответственно выбирать можно только длину ключа - 512 / 1024 / 2048 (по умолчанию, сертификат создается с длиной ключа 1024 бит).
  • dbo.spu_CryptAcquireContext_TestSpeed - измеряем скорость выполнения CryptoAPI функции CryptAcquireContext.

Шаг 2. Сохраняем с помощью процедуры dbo.spu_TDEForecast_SavePoint набор текущих значений из разных источников под некоторым именем (затем эти данные используются для составления прогноза). Например, это имя может быть 'test_start'.

Шаг 3. Запускаем нагрузку, для которой мы хотим составить прогноз. При этом нужно иметь в виду, что учитывается вся нагрузка на SQL севере, между начальной и конечной точками интервала. Прогноз строится для ситуации, когда TDE включается только для активной базы данных (это поведение можно легко изменить немного подправив код процедуры). Если нужно построить прогноз для некоторого запроса, то его нужно запустить. Другой активности на сервере в этот момент быть не должно.

Шаг 4. Опять сохраняем набор текущих значений из разных источников с помощью процедуры dbo.spu_TDEForecast_SavePoint, но под другим именем. Например под именем 'test_finish'.

Шаг 5. Считаем прогноз с помощью процедуры dbo.spu_TDEForecast_Result. Прогноз строится на основе данных о скорости выполнения криптографических операций полученных нами на шаге 1, и значений сохраненных нами с помощью процедуры dbo.spu_TDEForecast_SavePoint в начале исследуемого интервала (шаг 2) и конце интервала (шаг 4).

Подробное описание процедур

Процедура dbo.spu_CryptSymAlg_TestSpeed

Определяет скорость шифрования и расшифровки для указанного симметричного алгоритма.

Вызов:
  EXECUTE dbo.spu_CryptSymAlg_TestSpeed @alg_name
 
Параметры:

Параметр Тип Описание
@alg_name nvarchar(20) Имя алгоритма. Может принимать одно из следующих значений:
  • AES_128
  • AES_192
  • AES_256
  • TRIPLE_DES

Процедура dbo.spu_CryptAsymAlg_TestSpeed

Определяет скорость расшифровки для указанного асимметричного алгоритма.

Вызов:
  EXECUTE dbo.spu_CryptAsymAlg_TestSpeed @alg_name
 
Параметры:

Параметр Тип Описание
@alg_name nvarchar(20) Имя алгоритма. Может принимать одно из следующих значений:
  • RSA_512
  • RSA_1024
  • RSA_2048

Процедура dbo.spu_CryptAcquireContext_TestSpeed

Определяет скорость выполнения CryptoAPI функции CryptAcquireContext.

К сожалению, в SQL сервере нет операций, доступных для вызова из TSQL, позволяющих замерить скорость выполнения функции CryptAcquireContext в "чистом виде". По этой причине эта процедура возвращает очень примерную скорость. Однако дело спасает то обстоятельство, что влияние этого параметра на общий результат не очень значительно.
 
Вызов:
  EXECUTE dbo.spu_CryptAcquireContext_TestSpeed
 
Параметры: Нет

Процедура dbo.spu_TDEForecast_SavePoint

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

Значения сохраняются в таблицу dbo.__TDEMeasureData. При первом запуске процедуры dbo.spu_TdeForecast_SavePoint, эта таблица создается автоматически.
 
Вызов:
  EXECUTE dbo.spu_TDEForecast_SavePoint @point_name
 
Параметры:

Параметр Тип Описание
@point_name nvarchar(20) Имя, которое ассоциируется с сохраненными значениями

Процедура dbo.spu_TDEForecast_Result

Основная процедура. Возвращает значения, определяющие загрузку сервера на исследуемом интервале времени (длительность интервала, потребление процессора, объем ввода/вывода и т.д.) и то, как эти значения изменятся после включения TDE.

Вызов:
  EXECUTE dbo.spu_TdeForecast_Result @start_point, @end_point
       
[, @max_dop
        
, @V_sym_crypt, @V_sym_decrypt
        
, @V_asym_decrypt, @V_acquire_context]
 
Параметры:

Параметр   Описание
@start_point nvarchar(20) Имя точки определяющей начало интервала
@end_point nvarchar(20) Имя точки определяющей конец интервала
@max_dop int Ограничение на количество процессоров используемых при прогнозировании (нужно, если мы точно знаем, что исследуемый запрос не может использовать более некоторого числа процессоров)
@V_sym_crypt float Скорость шифрования в МБ / сек (значение определяется с помощью процедуры dbo.spu_CryptSymAlg_TestSpeed)
@V_sym_decrypt float Скорость расшифровки в МБ / сек (значение определяется с помощью процедуры dbo.spu_CryptSymAlg_TestSpeed)
@V_asym_decrypt float Скорость расшифровки симметричного ключа (DEK) зашифрованного ассиметричным алгоритмом в операциях / сек (значение определяется с помощью процедуры dbo.spu_CryptAsymAlg_TestSpeed)
@V_acquire_context float Скорость выполнения CryptoAPI функции CryptAcquireContext в операциях / сек (значение определяется с помощью процедуры dbo.spu_CryptAcquireContext_TestSpeed)

Пример 1. Много пишем

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

Отталкиваясь от вышесказанного, я выбрал два сценария для примеров, которые приведены далее. Первый пример - массированная вставка данных. Второй - запрос генерирующий большой объем физических чтений. Из-за большого объема ввода/вывода оба примера - это очень "неприятные" для TDE сценарии. Приводить пример, где напротив демонстрируется влияние TDE на приложения, которые не порождают ввода/выводя, я не стал, так как результат очевиден - никакого отрицательного влияния не будет.

Итак, в первом примере мы разберемся с тем как включение TDE отразится на выполнении массированной вставки. Сначала выполним тестовый запрос без TDE, посмотрим какую нагрузку он создаст, постараемся спрогнозировать как она изменится после включения TDE. Потом выполним запрос при включенном TDE и сравним прогноз с фактом.

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

EXECUTE dbo.spu_CryptSymAlg_TestSpeed 'AES_256'
EXECUTE dbo.spu_CryptAsymAlg_TestSpeed 'RSA_1024'
EXECUTE dbo.spu_CryptAcquireContext_TestSpeed

На моей машине получился следующий результат:

Прежде чем переходить непосредственно к тестам, давайте создадим базу данных, в которой будем экспериментировать:

-- Создаем тестовую базу данных
CREATE DATABASE TDE_TEST_DB
go
USE TDE_TEST_DB
go

Теперь можно пускать тестовую нагрузку:

SET NOCOUNT ON
-- Сохраняем значения из различных источников по состоянию на начало
EXECUTE dbo.spu_TDEForecast_SavePoint 'test1_start'

/*=== Начало тестового запроса ===*/

-- Создаем таблицу (если нет), куда будем вставлять данные
IF(OBJECT_ID('dbo.TestTable1') is not NULL)
    DROP TABLE dbo.TestTable1
CREATE TABLE dbo.TestTable1
(
    id int primary key,
    data varchar(200) not null
)
-- Вставляем в таблицу много строк
DECLARE @i int
SET @i = 0
BEGIN TRAN
WHILE(@i < 5000000) BEGIN
    INSERT dbo.TestTable1(id, data) VALUES(@i, REPLICATE('a', 200))
    SET @i = @i + 1
    IF(@i % 100 = 0) BEGIN
        COMMIT
        BEGIN TRAN
    END
END
IF
(@@TRANCOUNT > 0) COMMIT

/*=== Конец тестового запроса ===*/

-- Сохраняем значения из различных источников по состоянию на конец
EXECUTE dbo.spu_TDEForecast_SavePoint 'test1_finish'

Вот, как выглядит наш тестовый запрос в Мониторе производительности (красная кривая характеризует загрузку процессора в процентах, а синяя кривая - запись на диск в МБ / сек):

Теперь запросим прогноз:

EXECUTE dbo.spu_TDEForecast_Result
    @start_point = 'test1_start', @end_point = 'test1_finish',
    @max_dop = 1,
    @V_sym_crypt = 29.7, @V_sym_decrypt = 28.9,
    @V_asym_decrypt = 65.7, @V_acquire_context = 6100   

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

name value1 value2 unit Комментарий
--- PARAMETERS --- --- ПАРАМЕТРЫ ---
POINTs test1_start test1_finish   Начальная и конечная точки измерения (создаются процедурой dbo.spu_TDEForecast_SavePoint)
max_dop 1   cpu Ограничение на количество процессоров, используемых при прогнозировании (нужно, если мы точно знаем, что исследуемый запрос не может использовать более некоторого числа процессоров)
V_sym_crypt 29.7   MB / s_cpu Скорость шифрования в МБ / сек
V_sym_decrypt 28.9   MB / s_cpu Скорость расшифровки в МБ / сек
V_asym_decrypt 65.7   op / s_cpu Скорость расшифровки симметричного ключа (DEK) зашифрованного ассиметричным алгоритмом в операциях / сек
V_acquire_context 6100   op / s_cpu Скорость выполнения CryptoAPI функции CryptAcquireContext в операциях / сек
--- MEASURED DATA --- --- РЕЗУЛЬТАТЫ ИЗМЕРЕНИЯ ---
CPU_count 2   cpu Количество установленных в системе процессоров
CPU_enabled 1   cpu Количество процессоров, на которое будет ориентироваться прогноз
T_interval 193.14   s Длительность интервала времени между начальной и конечной точками измерения (время выполнения запроса) в секундах
C_interval 137.67   s_cpu Общая загрузка процессоров в течении всего интервала измерения в секундах процессора (каждый процессор / ядро считается отдельно)
C_system 3.18   s_cpu     Из них загрузка созданная системными процессами
        C_log_writer 1.87   s_cpu          Из них загрузка созданная Log Writer
        C_lazy_writer 0.02   s_cpu          Из них загрузка созданная Lazy Writer
        C_checkpoint 1.28   s_cpu          Из них загрузка созданная Checkpoint
Z_interval 0.71   s_cpu / s Средняя загрузка процессора в секунду (= C_interval / T_interval)
IO_data_read 0.01   MB / s Объем чтения из файлов данных в МБ / сек (в среднем по интервалу измерения)
IO_data_write 5.54   MB / s Объем записи в файлы данных в МБ / сек (в среднем по интервалу измерения)
IO_log_read 0   MB  / s Объем чтения из журналов транзакций в МБ / сек (в среднем по интервалу измерения)
IO_log_write 8.65   MB / s Объем записи в журналы транзакций в МБ / сек (в среднем по интервалу измерения)
IO_log_vfile 5777   vfile Количество виртуальных журналов транзакций, которые были созданы в течении интервала измерения
--- CALCULATED DATA --- --- ВЫЧИСЛЕНИЯ ---
C_TDE 269.26   s_cpu Объем дополнительной нагрузки на процессор, которая будет вызвана выполнением криптографических операций в TDE в секундах процессора (по всему интервалу измерения)
    C_sym_encrypt 92.24   s_cpu     Из них на шифрование
    C_sym_decrypt 40.79   s_cpu     Из них на расшифровку
    C_asym_decrypt 87.93   s_cpu     Из них на восстановление DEK (ключа шифрования)
    C_acquire_context 48.3   s_cpu     Из них на создание контекста для криптографических операций
--- FORECAST --- --- ПРОГНОЗИРОВАНИЕ ---
** Результатом прогноза являются интервалы значений, в которые скорее всего будут попадать прогнозируемые параметры (интервал определяется минимальным и максимальным значением)
TDE( T_interval ) 414.16 476.57 s Время, которое потребуется для выполнения того же объема работ в секундах
TDE( C_interval ) 393.45 420.4 s_cpu Будет всего потрачено секунд процессора (каждый процессор / ядро считается отдельно)
TDE( Z_interval ) 0.83 0.95 s_cpu / s Будет средняя загрузка процессора в секунду (= TDE(C_interval) / TDE(T_interval))
TDE( IO_data_read ) 0.01 0.01 MB / s Будет объем чтения из файлов данных в МБ / сек
TDE( IO_data_write ) 2.24 2.58 MB / s Будет объем записи в файлы данных в МБ / сек
TDE( IO_log_read ) 0 0 MB / s Будет объем чтения из журналов транзакций в МБ / сек
TDE( IO_log_write ) 3.5 4.03 MB / s Будет объем записи в журналы транзакций в МБ / сек

Теперь посмотрим как обстоят дела на самом деле. Для этого включим шифрование для тестовой базы данных:

USE master
-- Создаем главный ключ базы данных master (если он не был создан ранее)
IF(not EXISTS(SELECT * FROM sys.symmetric_keys WHERE name = '##MS_DatabaseMasterKey##'))
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'my$strong$pass0'
go
-- Создаем сертификат которым будет шифроваться DEK (Database Encryption Key)
CREATE CERTIFICATE DEK_EncCert WITH SUBJECT = 'DEK encryption certificate'
go
USE TDE_TEST_DB
go
-- Создаем DEK (Database Encryption Key)
CREATE DATABASE ENCRYPTION KEY WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE DEK_EncCert
go
-- Включаем шифрование
ALTER DATABASE TDE_TEST_DB SET ENCRYPTION ON
-- Ждем пока данные в базе данных будут полностью зашифрованы
WHILE(1=1) BEGIN
    WAITFOR DELAY '00:00:01'
    IF(EXISTS(SELECT * FROM sys.dm_database_encryption_keys
           WHERE
database_id = DB_ID('TDE_TEST_DB') And encryption_state = 3)) BREAK
END
-- Выводим состояние базы данных
SELECT DB_NAME(database_id), encryption_state FROM sys.dm_database_encryption_keys

Убеждаемся, что база данных теперь действительно зашифрована:

И опять запускаем тот же тест. В целях экономии места я не буду повторять листинг тестового запроса.

Далее приведен график из Монитора производительности. Для наглядности я совместил результаты с выключенным и включенным TDE на одном графике:

Небольшой комментарий: так как тестируемый запрос очевидно не может быть распараллелен, вся нагрузка, включая шифрование, ложится на один процессор (ядро). В силу этого, как видно из графика, загрузка процессора в секунду возросла не сильно (больше 100% никак). А вот длительность запроса возросла очень прилично, более чем в два раза. Это говорит о том, что на шифрование было потрачено много времени процессора. Сколько именно определяет площадь под красной кривой. Площадь под синей кривой определяет общий объем записи на диск сгенерированный запросом. Это значение, не должно было измениться и не изменилось, так как, очевидно, что на этот параметр TDE никак не влияет. Но так как длительность запроса возросла, объем записи в единицу времени заметно уменьшился (пропорционально).

Вот точные значения в табличном виде:

И наконец сводная таблица. Она содержит всю собранную информацию о выполнении тестового запроса с выключенным и включенным TDE, а так же прогноз.

   Показатель Значение без TDE Прогноз Значение с TDE % Комментарий
T_interval 193.14 414.16 - 476.57 462.19 239% Длительность интервала времени между начальной и конечной точками измерения (время выполнения запроса) в секундах
C_interval 137.67 393.45 - 420.4 414.41 301% Общая загрузка процессоров в течении всего интервала измерения в секундах процессора (каждый процессор / ядро считается отдельно)
     C_system 3.18   221.93       Из них загрузка созданная системными процессами
         C_log_writer 1.87   173.88            Из них загрузка созданная Log Writer
         C_lazy_writer 0.02   0.66            Из них загрузка созданная Lazy Writer
         C_checkpoint 1.28   46.35            Из них загрузка созданная Checkpoint
Z_interval 0.71 0.83 - 0.95 0.9 127% Средняя загрузка процессора в секунду (= C_interval / T_interval)
IO_data_read 0.01 0.01 0.01   Объем чтения из файлов данных в МБ / сек
IO_data_write 5.54 2.24 - 2.58 2.31 42%
(= 1/ 239%)
Объем записи в файлы данных в МБ / сек
IO_log_read 0 0 0   Объем чтения из журналов транзакций в МБ / сек
IO_log_write 8.65 3.5 - 4.03 3.61 42%
 (= 1/ 239%)
Объем записи в журналы транзакций в МБ / сек

Как видно из таблицы, фактические значения попали в прогнозируемый интервал :)

Пример 2. Много читаем

Давайте рассмотрим еще один пример. В отличии от предыдущего примера, где было много записи, здесь будет большой объем чтения. Кроме того, тестовый запрос в этом примере, в отличии от того, что мы использовали ранее, может быть распараллелен.

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

-- Выключаем шифрование
ALTER DATABASE TDE_TEST_DB SET ENCRYPTION OFF
-- Ждем пока данные в базе данных будут полностью расшифрованы
WHILE(1=1) BEGIN
    WAITFOR DELAY '00:00:01'
    IF(EXISTS(SELECT * FROM sys.dm_database_encryption_keys WHERE database_id = DB_ID('TDE_TEST_DB') And encryption_state = 1)) BREAK
END
-- Выводим состояние базы данных
SELECT DB_NAME(database_id), encryption_state FROM sys.dm_database_encryption_keys

Убеждаемся, что наша база данных действительно расшифрована:

Несмотря на то, что зашифрованных пользовательских баз данных на сервере больше нет, tempdb осталась зашифрована. Это не должно как-либо сказаться на результатах этого примера, так как ни явно, ни скрыто (план выполнения запроса этого не предусматривает) в tempdb мы ничего не пишем и не читаем.  Но для "чистоты эксперимента" можно перезапустить SQL сервер. После перезапуска tempdb уже не будет шифроваться.

Итак, выполняем тестовый запрос.

-- Сбрасываем кэш (нужно для улучшения повторяемости результатов)
CHECKPOINT
DBCC DROPCLEANBUFFERS

-- Сохраняем значения из различных источников по состоянию на начало
EXECUTE dbo.spu_TDEForecast_SavePoint 'test2_start'

/*=== Начало тестового запроса ===*/

SELECT data FROM dbo.TestTable1 UNION
SELECT data FROM dbo.TestTable1 UNION
SELECT data FROM dbo.TestTable1

/*=== Конец тестового запроса ===*/

-- Сохраняем значения из различных источников по состоянию на конец

EXECUTE dbo.spu_TDEForecast_SavePoint 'test2_finish'

Для выполнения этого запроса используется таблица dbo.TestTable1, которая была нами создана и заполнена данными в предыдущем примере. Приведенный выше тестовый запрос даже без шифрования достаточно прилично нагружает процессор из-за неявной опции DISTINCT (вспомним, что операция UNION без ALL возвращает только уникальные строки). План выполнения запроса предусматривает распараллеливание, то есть запрос сможет задействовать оба ядра процессора, установленных в тестовом сервере.

Смотрим какую нагрузку на сервер создал этот запрос:

Теперь запросим прогноз:

EXECUTE dbo.spu_TDEForecast_Result
    @start_point = 'test2_start', @end_point = 'test2_finish',
    @V_sym_crypt = 29.7, @V_sym_decrypt = 28.9,
    @V_asym_decrypt = 65.7, @V_acquire_context = 6100   

Вот что получилось (как и в первом примере, результат приводится в "разукрашенном" виде и c комментариями):

name value1 value2 unit Комментарий
--- PARAMETERS --- --- ПАРАМЕТРЫ ---
POINTs test2_start test2_finish   Начальная и конечная точки измерения (создаются процедурой dbo.spu_TDEForecast_SavePoint)
max_dop *   cpu Ограничение на количество процессоров, используемых при прогнозировании (нужно, если мы точно знаем, что исследуемый запрос не может использовать более некоторого числа процессоров)
V_sym_crypt 29.7   MB / s_cpu Скорость шифрования в МБ / сек
V_sym_decrypt 28.9   MB / s_cpu Скорость расшифровки в МБ / сек
V_asym_decrypt 65.7   op / s_cpu Скорость расшифровки симметричного ключа (DEK) зашифрованного ассиметричным алгоритмом в операциях / сек
V_acquire_context 6100   op / s_cpu Скорость выполнения CryptoAPI функции CryptAcquireContext в операциях / сек
--- MEASURED DATA --- --- РЕЗУЛЬТАТЫ ИЗМЕРЕНИЯ ---
CPU_count 2   cpu Количество установленных в системе процессоров
CPU_enabled 2   cpu Количество процессоров, на которое будет ориентироваться прогноз
T_interval 93.59   s Длительность интервала времени между начальной и конечной точками измерения (время выполнения запроса) в секундах
C_interval 91.5 s_cpu Общая загрузка процессоров в течении всего интервала измерения в секундах процессора (каждый процессор / ядро считается отдельно)
    C_system 0.05   s_cpu     Из них загрузка созданная системными процессами
       C_log_writer 0   s_cpu          Из них загрузка созданная Log Writer
       C_lazy_writer 0.05   s_cpu          Из них загрузка созданная Lazy Writer
        C_checkpoint 0   s_cpu          Из них загрузка созданная Checkpoint
Z_interval 0.98   s_cpu / s Средняя загрузка процессора в секунду (= C_interval / T_interval)
IO_data_read 33.72   MB / s Объем чтения из файлов данных в МБ / сек (в среднем по интервалу измерения)
IO_data_write 0   MB / s Объем записи в файлы данных в МБ / сек (в среднем по интервалу измерения)
IO_log_read 0   MB / s Объем чтения из журналов транзакций в МБ / сек (в среднем по интервалу измерения)
IO_log_write 0   MB / s Объем записи в журналы транзакций в МБ / сек (в среднем по интервалу измерения)
IO_log_vfile 0   vfile  Количество виртуальных журналов транзакций которые были созданы в течении интервала измерения
--- CALCULATED DATA --- --- ВЫЧИСЛЕНИЯ ---
C_TDE 109.23   s_cpu Объем дополнительной нагрузки на процессор, которая вызвана выполнением криптографических операция в TDE в секундах процессора (по всему интервалу измерения)
    C_sym_encrypt 0.01   s_cpu     Из них на шифрование
    C_sym_decrypt 109.22   s_cpu     Из них на расшифровку
    C_asym_decrypt 0   s_cpu     Из них на восстановление DEK (ключа шифрования)
    C_acquire_context 0   s_cpu     Из них на создание контекста для криптографических операций
--- FORECAST --- --- ПРОГНОЗИРОВАНИЕ ---
** Результатом прогноза являются интервалы значений, в которые скорее всего будут попадать прогнозируемые параметры (интервал определяется минимальным и максимальным значением)
TDE( T_interval ) 99.87 151.08 s Время, которое потребуется для выполнения того же объема работ, в секундах
TDE( C_interval ) 189.75 211.65 s_cpu Будет всего потрачено секунд процессора (каждый процессор / ядро считается отдельно)
TDE( Z_interval ) 1.26 1.9 s_cpu / s Будет средняя загрузка процессора в секунду (= TDE(C_interval) / TDE(T_interval))
TDE( IO_data_read ) 20.89 31.6 MB / s Будет объем чтения из файлов данных в МБ / сек
TDE( IO_data_write ) 0 0 MB / s Будет объем записи в файлы данных в МБ / сек
TDE( IO_log_read ) 0 0 MB / s Будет объем чтения из журналов транзакций в МБ / сек
TDE( IO_log_write ) 0 0 MB / s Будет объем записи в журналы транзакций в МБ / сек

Как и в первом примере, давайте сравним исходную загрузку и прогноз с реальной загрузкой после включения TDE.

Включаем шифрование тестовой базы данных:

-- Включаем шифрование
ALTER DATABASE TDE_TEST_DB SET ENCRYPTION ON
-- Ждем пока данные в базе данных будут полностью зашифрованы
WHILE(1=1) BEGIN
    WAITFOR DELAY '00:00:01'
    IF(EXISTS(SELECT * FROM sys.dm_database_encryption_keys WHERE database_id = DB_ID('TDE_TEST_DB') And encryption_state = 3)) BREAK
END
-- Выводим состояние базы данных
SELECT DB_NAME(database_id), encryption_state FROM sys.dm_database_encryption_keys

Убеждаемся, что база данных теперь опять зашифрована:

И повторяем тот же тест. Вот что получилось у меня:

Небольшой комментарий: можно констатировать, что здесь, как и в первом примере, включение TDE привело к появленью существенной дополнительной нагрузки на процессор (площадь под красной кривой). Однако в отличии от первого примера, за счет того, что план выполнения этого запроса допускает распараллеливание, загрузка процессора в секунду выросла очень прилично (ей было куда расти, так как в тестовой системе было установлено 2 ядра, и следовательно потолок - 200%).  За счет этого длительность запроса увеличилась не очень сильно. Как следствие объем чтения в единицу времени тоже снизился не очень сильно.

Точные значения в табличном виде:

Как и в первом примере, давайте сведем все вместе в одну таблицу:

   Показатель Значение без TDE Прогноз Значение с TDE % Комментарий
T_interval 93.59 99.87 - 151.08 118.33 126% Длительность интервала времени между начальной и конечной точками измерения (время выполнения запроса) в секундах
C_interval 91.5 189.75 - 211.65 192.09 211% Общая загрузка процессоров в течении всего интервала измерения в секундах процессора (каждый процессор / ядро считается отдельно)
     C_system 0.05   1.37       Из них загрузка созданная системными процессами
         C_log_writer 0   0            Из них загрузка созданная Log Writer
         C_lazy_writer 0.05   0.86            Из них загрузка созданная Lazy Writer
         C_checkpoint 0   0            Из них загрузка созданная Checkpoint
Z_interval 0.98 1.26 - 1.9 1.62 165% Средняя загрузка процессора в секунду (= C_interval / T_interval)
IO_data_read 33.72 20.89 - 31.6 26.67 79% (1 / 126%) Объем чтения из файлов данных в МБ / сек
IO_data_write 0 0 0   Объем записи в файлы данных в МБ / сек
IO_log_read 0 0 0   Объем чтения из журналов транзакций в МБ / сек
IO_log_write 0 0 0   Объем записи в журналы транзакций в МБ / сек

Как видно из таблицы фактические значения в этом примере так же попали в прогнозируемый интервал.

Заключение

Анализируя полученные результаты, можно сделать следующие выводы:

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

Несколько слов об ограничениях

SQL сервер - сложная система, способная на ходу подстраиваться под текущие условия. По этой причине один и то же запрос может выполняться совершенно по разному в разных условиях. Различные эффекты от взаимодействия множества запросов выполняющихся на одном сервере (блокировки и т.д.) тоже вносят элемент непредсказуемости. Представленное здесь решение этого не учитывает. При построении прогноза предполагается, что после включения TDE, запросы будут выполняться по той же схеме, что и без TDE. Чаще всего так оно и есть, но бывают и исключения.

<script src="http://www.google-analytics.com/urchin.js" type=text/javascript> </script> <script type=text/javascript> _uacct = "UA-2408004-1"; urchinTracker(); </script>
yliberman
07.05.2008 6:56
Комментариев:4 RSS Просмотров:401
Теги: Security, SQL, SQL 2008
Санитар
07.05.2008 20:20
Как тока я вижу столько графиков, сразу становится ясно, что блин, оверхед будет в десятки и сотни процентов, если не на порядки...
Ссылка
Alexey
08.05.2008 11:50
>Как тока я вижу столько графиков, сразу становится ясно, что блин, оверхед будет в десятки и сотни процентов, если не на порядки
а попробовать не судьба?
Ссылка
Yan Liberman
09.05.2008 6:37
> оверхед будет в десятки и сотни процентов, если не на порядки
Да, TDE вполне способно обеспечить очень приличный оверхед, но:
1. Все очень сильно зависит от приложения. Например, для многих сценариев оверхед от TDE будет стремиться к нулю.
2. Было бы неправильно винить в этом MS, шифрование таки действительно очень ресурсоемкая штука.
Ссылка
Yan Liberman
09.05.2008 9:16
Информация от MS по этому поводу (http://msdn.microsoft.com/en-us/libra...89384679):
The performance impact of TDE is minor. ...
In tests using sample data and TPC-C runs, the overall performance impact was estimated to be around 3-5% and can be much lower if most of the data accessed is stored in memory. Encryption is CPU intensive and is performed at I/O. Therefore, servers with low I/O and a low CPU load will have the least performance impact. Applications with high CPU usage will suffer the most performance loss, estimated to be around 28%.
Ссылка

Yan Liberman

yliberman разработчик
(none)
  • Блог

Облако тегов

advertisement bug scripting security sql sql 2008 sql ug

Записи

Популярные
  • k0stya > Система контроля версий для базы данных
  • Oxozle > Руководство по отладке многопоточных приложений в Visual Studio 2010
  • Jeje > Тюнинг производительно­сти для ASP.NET. Часть 1
  • Jeje > Razor - новый движок представлений в ASP.NET
  • Oxozle > Профилирование приложений в Visual Studio 2010
  • Jeje > NerdDinner. Шаг 1: Новый проект
  • Oxozle > Visual Studio 2010 Productivity Power Tools
  • sergeypopov > Ссылки к докладу «Расширяем Visual Studio 2010»
  • Jeje > NerdDinner. Шаг 2: Создание базы данных
  • mezastel > Паттерн-мэтчинг на языке C#
Все популярные записи
Обсуждаемые
  • k0stya > Система контроля версий для базы данных
  • Oxozle > Руководство по отладке многопоточных приложений в Visual Studio 2010
  • XaocCPS > Срочно! Вышел Razor View Engine и открыто имя нового проекта WebMatrix
  • mvcdev > Локализация ASP.NET приложений. Стиль кодирования
  • XaocCPS > Pivot-коллекция (silverlight) для навигации по статьям журнала MSDN Magazine
  • Jeje > NerdDinner. Шаг 2: Создание базы данных
  • Sharomank > Расширение Regex Tester для Visual Studio 2010
  • XaocCPS > Анонсирован SQL Server Compact Edition 4
  • Oxozle > Visual Studio 2010 Productivity Power Tools
  • XaocCPS > Выпущена библиотека ADO.NET Entity Framework Feature CTP 4
Все обсуждаемые записи

Блоги

Новые
  • Stanislav Gornakov [MVP]> Stanislav Gornakov
  • k0stya> k0stya
  • ][tiger> Just do IT - просто дует
  • Oxozle> KLUBS
  • mvcdev> WebDev
  • VitaliyP> PanarinV
  • Tamifist> Tamifist
  • kir> KLypkan
  • sadomovalex> Alexey Sadomov
  • noetic> Систематизация автоматизации
Обсуждаемые
  • mihailik> Олег Михайлик
  • ceo> Нотатник Вiктора Шатохiна [MSFT]
  • gaidar> Gaidar Magdanurov
  • MikhailChernomo­rdikov> Mikhail Chernomordikov [MSFT]
  • Alexander Lozhechkin [MSFT]> Alexander Lozhechkin
  • agladkik> Andrey Gladkikh: Microsoft Dynamics
  • sergun> Sergey Zwezdin
  • beerbong> Bong Blog
  • sos> Dmitry Soshnikov [MSFT]
  • not-a-kernel-gu­y> Зеркало: Not a kernel guy
О сайте   Свяжитесь с нами   Версия для печати
Работает на 1С-Битрикс: Управление сайтом ASP.NET  |  Хостинг на Parking.Ru