Подтвердить что ты не робот

Как получить общее количество элементов в таблице DynamoDB?

Я хочу знать, сколько элементов находится в моей таблице dynamodb. Из руководства API один из способов сделать это - scan следующим образом:

<?php
$dynamodb = new AmazonDynamoDB();

$scan_response = $dynamodb->scan(array(
    'TableName' => 'ProductCatalog' 
));

echo "Total number of items: ".count($scan_response->body->Items)."\n";

Однако это должно извлекать все элементы и хранить их в массиве в памяти, который невозможен в большинстве случаев, я бы предположил. Есть ли способ получить общее количество предметов более эффективно?

Эти данные недоступны в веб-консоли AWS Dynamo, я уже проверил. (сначала это выглядит так, как показано рядом с кнопками разбиения на страницы, но оказывается, что фигура растет, когда вы переходите на следующую страницу элементов).

4b9b3361

Ответ 1

Я могу представить три варианта, чтобы получить общее количество элементов в таблице DynamoDB.

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

  • Второй вариант - это то, что было сказано Atharva:

    Лучшим решением, которое приходит мне на ум, является поддержание общего количество отсчетов элементов для таких таблиц в отдельной таблице, где каждый item будет иметь имя таблицы как хэш-ключ и общее количество элементов в этой таблице в качестве не-ключевого атрибута. Затем вы можете сохранить эту таблицу возможно, названный "TotalNumberOfItemsPerTable", обновленный путем создания атомарного операции обновления для увеличения/уменьшения общего количества элементов для конкретную таблицу.

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

  • Простейшим решением является DescribeTable, который возвращает ItemCount. Единственная проблема заключается в том, что счетчик не обновляется. Счет обновляется каждые 6 часов.

http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html

Ответ 2

Параметр Count определенно то, что вы хотите, но вы также должны учитывать, что в результатах сканирования может быть одна или несколько страниц. Операция Scan только сканирует 1MB данных в вашей таблице за раз, поэтому значение Count в результате будет отражать только количество первых 1MB таблицы. Вам нужно будет сделать последующие запросы, используя значение LastEvaluatedKey в результате (если оно есть). Вот пример кода для этого:

<?php

$dynamo_db = new AmazonDynamoDB();

$total = 0;
$start_key = null;
$params = array(
    'TableName' => 'my-table',
    'Count'     => true
);

do {
    if ($start_key) {
        $params['ExclusiveStartKey'] = $start_key->getArrayCopy();
    }

    $response = $dynamo_db->scan($params);

    if ($response->isOK()) {
        $total += (string) $response->body->Count;

        if ($response->body->LastEvaluatedKey) {
            $start_key = $response->body->LastEvaluatedKey->to_array();
        } else {
            $start_key = null;
        }
    }
} while ($start_key);

echo "Count: {$total}";

Ответ 4

Если вы заинтересованы в использовании общего количества элементов в таблице в логике вашего приложения, это означает, что вы часто будете запрашивать общий счет. Теперь одним из способов достижения этой цели является использование операции сканирования. Но помните, что операция сканирования буквально сканирует всю таблицу и поэтому потребляет большую пропускную способность, поэтому все операции запроса будут получать Throttled Exception в этой длительности. И даже учитывая тот факт, что сканирование ограничит итоговый счет размером 1 МБ, вам придется выполнять повторные операции сканирования, чтобы получить фактическое количество элементов, если таблица очень велика. Для этого потребуется написать пользовательскую логику запроса и обработать неизбежное дросселирование в операциях запроса.

Лучшим решением, которое приходит мне на ум, является поддержание общего количества подсчетов элементов для таких таблиц в отдельной таблице, где каждый элемент будет иметь имя таблицы как хэш-ключ и общее количество элементов в этой таблице, -key. Затем вы можете сохранить эту таблицу с именем "TotalNumberOfItemsPerTable", обновив ее, сделав операции атомного обновления для увеличения/уменьшения общего количества элементов для конкретной таблицы.

Отсутствует проблема дросселирования или ограничение 1 МБ.

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

Ответ 5

Примерное значение счетчика элементов (предположительно обновляемое каждые шесть часов) доступно на консоли AWS для DynamoDB. Просто выберите таблицу и посмотрите под вкладкой "Сведения", последняя запись - "Количество элементов". Если это сработает для вас, вы можете избежать потребления вашей таблицы пропускной способности, чтобы сделать счет.

Ответ 6

Теперь это доступно на экране обзора таблицы AWS в разделе "Данные таблицы", поле "Количество элементов". Кажется, это всего лишь свалка DescribeTable и отмечает, что ее обновление примерно каждые шесть часов.

Ответ 7

Здесь, как я получаю точный счетчик предметов на моем биллинге записей таблицы DynamoDB:

Улей >

set dynamodb.throughput.write.percent = 1;
set dynamodb.throughput.read.percent = 1;
set hive.execution.engine = mr;
set mapreduce.reduce.speculative=false;
set mapreduce.map.speculative=false;

CREATE EXTERNAL TABLE dynamodb_table (`ID` STRING,`DateTime` STRING,`ReportedbyName` STRING,`ReportedbySurName` STRING,`Company` STRING,`Position` STRING,`Country` STRING,`MailDomain` STRING) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "BillionData", "dynamodb.column.mapping" = "ID:ID,DateTime:DateTime,ReportedbyName:ReportedbyName,ReportedbySurName:ReportedbySurName,Company:Company,Position:Position,Country:Country,MailDomain:MailDomain");

SELECT count(*) FROM dynamodb_table;

* У вас должен быть кластер EMR, который устанавливается с помощью обработчика Hive и DynamoDB. * С помощью этой команды обработчик DynamoDB на улье выдает "ПАРАЛЛЕЛЬНЫЕ СКАНИРОВАНИЯ" с несколькими Mapperduce mappers (AKA Workers), работающими на разных разделах, чтобы получить счет. Это будет намного эффективнее и быстрее, чем обычное сканирование. * Вы должны быть готовы увеличить производительность чтения в течение определенного периода времени. * В приличном размере (20 node) кластер, с 10000 RCU, потребовалось 15 минут, чтобы получить счет на миллиард записей Приблиз.
* Новые записи в этой таблице DDB в течение этого периода сделают счет непоследовательным.