#amazon-web-services #amazon-s3 #aws-lambda #amazon-athena #partition
#amazon-web-services #amazon-s3 #aws-lambda #amazon-athena #раздел
Вопрос:
У нас есть журналы балансировки нагрузки приложений в s3, которые мы запрашиваем с помощью Athena. Мы хотели бы добавить разделы для года, месяца, даты.
Я следую официальной документации AWS, которая перенаправляет на страницу github для добавления разделов в таблицу.
Я следовал руководству, но когда я когда-либо создаю таблицу с разделами, либо записи не возвращаются, либо они пусты.
CREATE EXTERNAL TABLE IF NOT EXISTS alb_logs (
type string,
time string,
elb string,
client_ip string,
client_port int,
target_ip string,
target_port int,
request_processing_time double,
target_processing_time double,
response_processing_time double,
elb_status_code string,
target_status_code string,
received_bytes bigint,
sent_bytes bigint,
request_verb string,
request_url string,
request_proto string,
user_agent string,
ssl_cipher string,
ssl_protocol string,
target_group_arn string,
trace_id string,
domain_name string,
chosen_cert_arn string,
matched_rule_priority string,
request_creation_time string,
actions_executed string,
redirect_url string,
error_reason string
)
PARTITIONED BY(year string, month string, day string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1',
'input.regex' =
'([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) "([^ ]*) ([^ ]*) (- |[^ ]*)" "([^"]*)" ([A-Z0-9-] ) ([A-Za-z0-9.-]*) ([^ ]*) "([^"]*)" "([^"]*)" "([^"]*)" ([-.0-9]*) ([^ ]*) "([^"]*)" "([^ ]*)" "([^ ]*)"' )
LOCATION 's3://{LOG_BUCKET}/AWSLogs/{AWS_account_ID}/elasticloadbalancing/us-east-1/';
(мы не используем префикс в наших журналах)
Если я удалю PARTITIONED BY(year string, month string, day string)
часть, то у меня будет создана соответствующая таблица без разделов, из которой я могу запрашивать данные.
Когда я добавляю часть раздела, я получаю 0 записей. Читая дальше, насколько я понимаю, мне нужно добавить эти разделы. С этой страницы github
Этот шаблон создает лямбда-функцию для добавления раздела и запланированного события CloudWatch. Журналы отправляются из балансировщика нагрузки в корзину S3. Ежедневно запланированное событие CloudWatch вызывает функцию Lambda для добавления раздела в таблицу Athena.
Но, честно говоря, я не совсем понимаю эту часть. Однако я пошел дальше и развернул предоставленный шаблон CloudFormation с соответствующими параметрами. Однако теперь я получаю возвращаемые записи для простого запроса select all
select * from alb_logs where year = '2020' and month "12" limit 100
все поля пусты, кроме ключей раздела year
, month
и day
(они не были без partition
участия в create table
command, что для меня указывает на то, что регулярное выражение не является проблемой)
Любая помощь в понимании того, что я делаю неправильно, и как правильно это настроить, будет высоко оценена.
Ответ №1:
Это не имеет никакого отношения к разделам. Вероятно, это проблема с характером персонажа. Возможно, новая строка в конце вашего ввода. регулярное выражение в определении таблицы или что-то в этом роде. Проверьте мой рабочий пример в файле cloudformation yml для таблицы, настроенной для ведения журнала балансировщика нагрузки:
AlbAthenaTable:
Type: AWS::Glue::Table
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseName: !Ref AthenaDataBase
TableInput:
Name:
!Join
- '_'
- !Split
- '-'
- !Sub ${AWS::StackName}_alb_table
TableType: EXTERNAL_TABLE
Parameters: {
"projection.day.type": "integer",
"projection.day.range": "1,31",
"projection.enabled": "true" }
PartitionKeys:
- Name: day
Type: int
StorageDescriptor:
OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Columns:
- Name: type
Type: string
- Name: time
Type: string
- Name: elb
Type: string
- Name: client_ip
Type: string
- Name: client_port
Type: int
- Name: target_ip
Type: string
- Name: target_port
Type: int
- Name: request_processing_time
Type: double
- Name: target_processing_time
Type: double
- Name: response_processing_time
Type: double
- Name: elb_status_code
Type: string
- Name: target_status_code
Type: string
- Name: received_bytes
Type: bigint
- Name: sent_bytes
Type: bigint
- Name: request_verb
Type: string
- Name: request_url
Type: string
- Name: request_proto
Type: string
- Name: user_agent
Type: string
- Name: ssl_cipher
Type: string
- Name: ssl_protocol
Type: string
- Name: target_group_arn
Type: string
- Name: trace_id
Type: string
- Name: domain_name
Type: string
- Name: chosen_cert_arn
Type: string
- Name: matched_rule_priority
Type: string
- Name: request_creation_time
Type: string
- Name: actions_executed
Type: string
- Name: redirect_url
Type: string
- Name: lambda_error_reason
Type: string
- Name: target_port_list
Type: string
- Name: target_status_code_list
Type: string
- Name: classification
Type: string
- Name: classification_reason
Type: string
InputFormat: org.apache.hadoop.mapred.TextInputFormat
Location:
!Sub s3://${LoggingBucket}/${Prefix}/
SerdeInfo:
Parameters:
serialization.format: 1
input.regex: >-
([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) "([^ ]*) ([^ ]*) (- |[^ ]*)" "([^"]*)" ([A-Z0-9-] ) ([A-Za-z0-9.-]*) ([^ ]*) "([^"]*)" "([^"]*)" "([^"]*)" ([-.0-9]*) ([^ ]*) "([^"]*)" "([^"]*)" "([^ ]*)" "([^s] ?)" "([^s] )" "([^ ]*)" "([^ ]*)"
SerializationLibrary: org.apache.hadoop.hive.serde2.RegexSerDe
вам нужно перейти в консоль каталога данных aws glue и проверить ваше регулярное выражение input.regex в SerderInfo в свойствах таблицы и убедиться, что оно выглядит следующим образом:
"input.regex": "([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) "([^ ]*) ([^ ]*) (- |[^ ]*)" "([^"]*)" ([A-Z0-9-] ) ([A-Za-z0-9.-]*) ([^ ]*) "([^"]*)" "([^"]*)" "([^"]*)" ([-.0-9]*) ([^ ]*) "([^"]*)" "([^"]*)" "([^ ]*)" "([^s] ?)" "([^s] )" "([^ ]*)" "([^ ]*)""
вместо:
"input.regex": "([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) "([^ ]*) ([^ ]*) (- |[^ ]*)" "([^"]*)" ([A-Z0-9-] ) ([A-Za-z0-9.-]*) ([^ ]*) "([^"]*)" "([^"]*)" "([^"]*)" ([-.0-9]*) ([^ ]*) "([^"]*)" "([^"]*)" "([^ ]*)" "([^s] ?)" "([^s] )" "([^ ]*)" "([^ ]*)"n"
здесь важно отметить, что у вас не может быть новой строки (ни пробелов, ни других символов) в конце вашего ввода.регулярное выражение! Если это так, вы получите сообщение об ошибке, о котором сообщили.
Я рекомендую вам создать таблицу, аналогичную примеру документации. после этого создайте свой и, если у вас возникнут какие-либо проблемы, проверьте, нет ли различий между их настройками.
Пример документации:
https://docs.aws.amazon.com/athena/latest/ug/application-load-balancer-logs.html
Еще одна вещь (немного не по теме, но очень полезная для ваших целей) заключается в том, что вы можете использовать функцию, называемую partitions-projection, для прогнозирования разделов на уровне определения таблицы. Если вы используете эту функцию, вам вообще не нужно вручную добавлять новые разделы или использовать для этого планировщик с лямбдой.
Проверьте документы:
https://docs.aws.amazon.com/athena/latest/ug/partition-projection.html#partition-projection-using
Я также использую эту функцию в своем шаблоне, в этой части:
...
TableInput:
...
Parameters: {
"projection.day.type": "integer",
"projection.day.range": "1,31",
"projection.enabled": "true" }
PartitionKeys:
- Name: day
Type: int
....
в моем случае я просто использую целое число. Но прогнозирование разделов поддерживает тип даты и другие типы.
Еще один совет не по теме:
Я знаю, что разделение и весь этот процесс могут быть немного сложными, поэтому вот статья, в которой весь этот процесс объясняется очень глубоко и очень понятно (речь идет о cloudfront, но основы те же):
https://aws.amazon.com/blogs/big-data/analyze-your-amazon-cloudfront-access-logs-at-scale/
Вот репозиторий github, связанный со статьей выше, он очень полезен:
https://github.com/aws-samples/amazon-cloudfront-access-logs-queries