Задержка Aurora vs DynamoDB не такая, как ожидалось

#go #amazon-dynamodb #latency #aws-sdk-go #amazon-aurora

#Вперед #amazon-dynamodb #задержка #aws-sdk-go #amazon-aurora

Вопрос:

Я хотел получить некоторые цифры, чтобы доказать, что, по моим данным, хранилище ключ-значение DynamoDB обладает лучшей производительностью чтения по сравнению с реляционной БД (MySQL, PostgreSQL, Aurora). Поэтому я решил сравнить задержки ЧТЕНИЯ DynamoDB и AWS-Aurora (которая подключена к веб-сайту AWS — «в пять раз быстрее, чем стандартные базы данных MySQL, и в три раза быстрее, чем стандартные базы данных PostgreSQL»)

Шаг 1: создал таблицу в Aurora со следующей схемой и добавил в эту таблицу 1,02 миллиона записей.

 Table gift_log (
  gift_uuid               BINARY(16) NOT NULL,
  user_uuid               BINARY(16) NOT NULL,
  parent_uuid             BINARY(16),
  operation_time          TIMESTAMP,
  operation               VARCHAR(20) NOT NULL,
  gift_type               VARCHAR(20) NOT NULL,
  parent_type             VARCHAR(20),
  relation_type           VARCHAR(20),
  PRIMARY KEY (gift_uuid)
);
  

Используется клиент Golang, который использует драйвер MySQL для пакета базы данных / sql для запроса таблицы.

Шаг 2; Создана таблица DynamoDB со следующими атрибутами. Добавлено 1 миллион элементов в таблицу. НЕ использовался какой-либо ключ сортировки. Во всех запросах использовался ключ раздела.

 
Table: GiftLog {
    gift_uuid               Binary (Partition Key)
    user_uuid               Binary
    operation_time          Number,
    operation               String,
    gift_type               String,
    parent_type             String
}
  

Используется клиент Golang, который использует AWS Go-SDK для запроса таблицы DynamoDB.

АВРОРА

 startTime := time.Now().UnixNano()

rows, err := db.Query("SELECT * FROM gift_log WHERE gift_uuid=?", giftIDsToRead[i])

endTimt := time.Now().UnixNano()
  

DynamoDB

 queryInput := amp;dynamodb.QueryInput{
        TableName: aws.String(tableName),
        KeyConditions: map[string]*dynamodb.Condition{
                        "GiftUUID": {
                            ComparisonOperator: aws.String("EQ"),
                            AttributeValueList: []*dynamodb.AttributeValue{
                                {
                                    B: giftIDsToRead[i],
                                },
                            },
                        },
        },
}

startTime := time.Now().UnixNano()

resp, err := svc.Query(queryInput)

endTime := time.Now().UnixNano()
  

Задержка Aurora: 543,89 Задержка DynamoDB: 2934,96 usec

Эти цифры не кажутся правильными. Разве я не сравниваю яблоки с яблоками?

Комментарии:

1. Каковы были ваши цифры?

2. Используете ли вы VPC для подключения к AuroraDB, а звонки в Dynamo осуществляются через VPC или интернет?

Ответ №1:

Вы не показываете результаты синхронизации… но я бы сказал, что вы сравниваете яблоки с апельсинами. Если вы знаете первичный ключ элемента DynamoDB, вы должны использовать GetItem(), а не Query() .

При использовании GetItem() время отклика должно составлять «однозначную миллисекунду»; исключая задержку в сети / HTTP

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

Комментарии:

1. Исправлено, чтобы использовать GetItem вместо запроса. Cloudwatch действительно показывает, что задержка DynamoDB составляет 2,08 мс.

Ответ №2:

Я думаю, вы упускаете несколько очень важных моментов.

  1. DynamoDB — это «база данных как сервис», тогда как Aurora — более традиционная база данных
  2. Всякий раз, когда вы проводите сравнительный анализ производительности или любой другой, вы не можете просто выполнить один тест: вам нужно выполнить множество тестов, а затем вычислить статистику, такую как среднее значение, или, что еще лучше, верхний процентиль (скажем, 99-й процентиль)
  3. DynamoDB работает, когда вам нужна «предсказуемая производительность в любом масштабе»

Первый момент важен, потому что это означает, что для получения данных из DynamoDB вы выполняете веб-запросы, которые имеют некоторую степень накладных расходов по сравнению с более традиционной базой данных. Эти накладные расходы могут составлять порядка 1-2 миллисекунд на запрос. Но, по-видимому, это нормально в контексте большинства приложений, если приложение хорошо спроектировано и не выполняет кучу ненужных запросов.

Второй момент важен, потому что, если вы не посмотрите на него правильно, вы можете измерить выбросы: это означает, что вы можете увидеть некоторые результаты, которые не соответствуют типичной производительности и могут потратить много времени на поиск отвлекающих маневров. Вместо того, чтобы измерять производительность одного запроса, измерьте производительность многих однотипных запросов и вычислите некоторые статистические данные, например: среднее и стандартное отклонение; или n-й процентиль (50-й, 90-й, 99-й являются типичными)

Последний пункт — это тот, который в значительной степени мотивирует использование DynamoDB по сравнению с классическим ядром базы данных. Вы смотрите на самый счастливый из счастливых случаев: (предположительно) небольшая таблица с несколькими элементами, из которых вы извлекаете один, используя его первичный ключ. DynamoDB — это действительно все о том, что происходит по мере роста ваших данных с течением времени. Вы хотите иметь ту же производительность при извлечении этого элемента сейчас, когда в вашей таблице 1000 элементов, что и когда в вашей таблице 100 000 000 элементов. И все становится интереснее с более сложными запросами.

С DynamoDB вы обмениваете небольшие накладные расходы на производительность в простейших случаях для обеспечения стабильности.

Но DynamoDB не панацея! Бывают ситуации, когда реляционная база данных всегда превосходит DynamoDB.