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

Я хотел получить некоторые цифры, чтобы доказать, что я прочитал, что хранилище DynamoDB Key-Value имеет лучшую производительность чтения по сравнению с реляционными БД (MySQL, PostgreSQL, Aurora). Поэтому я решил сравнить задержки READ 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 для пакета database / 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 := &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 мкс

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


person Korba    schedule 08.04.2019    source источник
comment
Какие у вас были числа?   -  person John Rotenstein    schedule 09.04.2019
comment
Вы используете VPC для подключения к AuroraDB, а звонки в Dynamo осуществляются через VPC или Интернет?   -  person Ankit Deshpande    schedule 09.04.2019


Ответы (2)


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

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

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

person Charles    schedule 08.04.2019
comment
Исправлено использование GetItem вместо Query. Cloudwatch действительно показывает, что задержка DynamoDB составляет 2,08 мс. - person Korba; 09.04.2019

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

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

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

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

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

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

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

person Mike Dinescu    schedule 09.04.2019