Entendo que você está procurando uma prova firme de se as solicitações GET que retornam um 304 são contadas como uma solicitação GET para fins de faturamento, da mesma forma que uma solicitação GET retornando um 200 é.
A documentação não menciona nenhuma diferença de faturamento com base no código de status HTTP retornado, mas isso não oferece nenhuma prova de uma forma ou de outra. Para fornecer uma resposta firme, eu configuro um Relatório de custo e uso para minha conta com a frequência de agregação definida como IDs por hora e recursos incluídos, e depois testei isso e observei o que apareceu no relatório.
TLDR; O relatório de faturamento confirma o que todos esperavam, um GET é faturado como GET, se retorna um código de status de 200 ou 304.
Configuração de teste
Selecionei um bucket do S3 publicamente legível e não usado, carreguei um arquivo de imagem e configurei um cabeçalho HTTP de Cache-Control: public, max-age = 10 no arquivo. Isso significa que, se a página for recarregada após 10 segundos, o navegador deverá verificar com o servidor para ver se o arquivo foi alterado antes de usar sua cópia em cache local.
Para garantir que o teste seja repetível e não tenha nenhum resultado inesperado (por exemplo, de um erro de digitação etc.), criei um arquivo html local que exibiria a imagem.
<html>
<body>
<img src="http://mybucket.s3.amazonaws.com/5DS05736-2.jpg"width="868" height="488" />
</body>
</html>
A razão para manter isso em minha máquina local era evitar quaisquer solicitações ao S3 para coisas como favicon (o que potencialmente poluiria os resultados).
Confirmar o teste funcionaria
Eu realizei um teste inicial no chrome abrindo as ferramentas do desenvolvedor, procurando na guia de rede e carregando meu arquivo html local. Na primeira solicitação, a imagem foi carregada com um Código de Status HTTP de 200. A espera e a atualização da página mostraram que a imagem estava sendo carregada uma segunda vez com um Código de Status HTTP de 304.
Limpei o cache de entradas da última hora.
Teste real
Na manhã seguinte, repeti o experimento. Para ter certeza de que eu poderia distinguir entre os testes da noite anterior e o teste real, observei a hora e os códigos de status que recebi. Fiz uma carga sem a imagem no cache, resultando em 200 e, em seguida, duas atualizações ~ 20 segundos, resultando em 304s.
Isso daria as seguintes possibilidades no relatório de faturamento:
- 1 GET Request = Somente solicitações GET retornando 200 são contadas
- 2 solicitações GET = somente as solicitações GET que retornam 304 são contadas (pouco provável)
- 3 GET Requests = todas as solicitações GET são contadas
O relatório de faturamento
Esperei até que o relatório de faturamento estivesse disponível e o coloquei em Athena. Se você está repetindo isso, o comando Athena CREATE TABLE é:
CREATE EXTERNAL TABLE 'cost_and_usage'(
'identity_lineitemid' string,
'identity_timeinterval' string,
'bill_invoiceid' string,
'bill_billingentity' string,
'bill_billtype' string,
'bill_payeraccountid' string,
'bill_billingperiodstartdate' string,
'bill_billingperiodenddate' string,
'lineitem_usageaccountid' string,
'lineitem_lineitemtype' string,
'lineitem_usagestartdate' string,
'lineitem_usageenddate' string,
'lineitem_productcode' string,
'lineitem_usagetype' string,
'lineitem_operation' string,
'lineitem_availabilityzone' string,
'lineitem_resourceid' string,
'lineitem_usageamount' string,
'lineitem_normalizationfactor' string,
'lineitem_normalizedusageamount' string,
'lineitem_currencycode' string,
'lineitem_unblendedrate' string,
'lineitem_unblendedcost' string,
'lineitem_blendedrate' string,
'lineitem_blendedcost' string,
'lineitem_lineitemdescription' string,
'lineitem_taxtype' string,
'product_productname' string,
'product_accountassistance' string,
'product_architecturalreview' string,
'product_architecturesupport' string,
'product_availability' string,
'product_bestpractices' string,
'product_cacheengine' string,
'product_caseseverityresponsetimes' string,
'product_clockspeed' string,
'product_currentgeneration' string,
'product_customerserviceandcommunities' string,
'product_databaseedition' string,
'product_databaseengine' string,
'product_dedicatedebsthroughput' string,
'product_deploymentoption' string,
'product_description' string,
'product_durability' string,
'product_ebsoptimized' string,
'product_ecu' string,
'product_endpointtype' string,
'product_enginecode' string,
'product_enhancednetworkingsupported' string,
'product_executionfrequency' string,
'product_executionlocation' string,
'product_feecode' string,
'product_feedescription' string,
'product_freequerytypes' string,
'product_freetrial' string,
'product_frequencymode' string,
'product_fromlocation' string,
'product_fromlocationtype' string,
'product_group' string,
'product_groupdescription' string,
'product_includedservices' string,
'product_instancefamily' string,
'product_instancetype' string,
'product_io' string,
'product_launchsupport' string,
'product_licensemodel' string,
'product_location' string,
'product_locationtype' string,
'product_maxiopsburstperformance' string,
'product_maxiopsvolume' string,
'product_maxthroughputvolume' string,
'product_maxvolumesize' string,
'product_maximumstoragevolume' string,
'product_memory' string,
'product_messagedeliveryfrequency' string,
'product_messagedeliveryorder' string,
'product_minvolumesize' string,
'product_minimumstoragevolume' string,
'product_networkperformance' string,
'product_operatingsystem' string,
'product_operation' string,
'product_operationssupport' string,
'product_physicalprocessor' string,
'product_preinstalledsw' string,
'product_proactiveguidance' string,
'product_processorarchitecture' string,
'product_processorfeatures' string,
'product_productfamily' string,
'product_programmaticcasemanagement' string,
'product_provisioned' string,
'product_queuetype' string,
'product_requestdescription' string,
'product_requesttype' string,
'product_routingtarget' string,
'product_routingtype' string,
'product_servicecode' string,
'product_sku' string,
'product_softwaretype' string,
'product_storage' string,
'product_storageclass' string,
'product_storagemedia' string,
'product_technicalsupport' string,
'product_tenancy' string,
'product_thirdpartysoftwaresupport' string,
'product_tolocation' string,
'product_tolocationtype' string,
'product_training' string,
'product_transfertype' string,
'product_usagefamily' string,
'product_usagetype' string,
'product_vcpu' string,
'product_version' string,
'product_volumetype' string,
'product_whocanopencases' string,
'pricing_leasecontractlength' string,
'pricing_offeringclass' string,
'pricing_purchaseoption' string,
'pricing_publicondemandcost' string,
'pricing_publicondemandrate' string,
'pricing_term' string,
'pricing_unit' string,
'reservation_availabilityzone' string,
'reservation_normalizedunitsperreservation' string,
'reservation_numberofreservations' string,
'reservation_reservationarn' string,
'reservation_totalreservednormalizedunits' string,
'reservation_totalreservedunits' string,
'reservation_unitsperreservation' string,
'resourcetags_username' string,
'resourcetags_usercostcategory' string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
WITH SERDEPROPERTIES (
'escape.delim'='\')
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
's3://my-billing-bucket/reports/hourly/20180501-20180601/dcd20d15-fffd-4a40-bc5d-555f32fc64b2'
TBLPROPERTIES (
'skip.header.line.count'='1')
E a consulta para reduzi-lo ao uso que você está procurando é:
select * from cost_and_usage where lineitem_resourceid = 'my-bucket' and lineitem_operation = 'GetObject' and lineitem_usagetype = 'USW2-Requests-Tier2' order by lineitem_usagestartdate desc
Você precisará alterar my-bucket e USW2-Requests-Tier2 para os valores apropriados para o local do bucket e do bucket, etc.
Para a hora em que realizei meu teste, a coluna lineitem_usageamount lista três solicitações. Isso significa que todos os meus pedidos foram cobrados.
Se você está se perguntando como posso ter certeza de que nenhum outro uso do intervalo aconteceu, eu tenho o CloudTrail com o registro do S3 ativado e apontando para os Registros do CloudWatch. Usando isso, consegui verificar se nenhuma outra solicitação foi feita para o intervalo naquele momento. :)