AWS PINPOINT

AWS์˜ Amazon Pinpoint์—๋Š” Event๋ฅผ ์ €์žฅํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค.

Event Stream์ด๋ผ ํ•˜์—ฌ, Amazon Pinpoint์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ๋กœ๊ทธ๋ฅผ AWS Kinesis๋กœ ๋ณด๋‚ด๋Š” ๊ธฐ๋Šฅ์ธ๋ฐ, ๋‚˜๋Š” ๋ณดํ†ต Elasticsearch๋กœ ๋ณด๋‚ด์–ด ๋กœ๊ทธ๋ฅผ ๊ด€๋ฆฌ ํ•œ๋‹ค. ์ดํ›„ Kibana๋ฅผ ํ†ตํ•ด BI๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ์“ด๋‹ค.

Pinpoint EventStream ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™” ํ•˜์—ฌ Kinesis Firehose๋ฅผ ํ†ตํ•ด Elasticsearch๋กœ ๋ณด๋‚ด๋„๋ก ๊ตฌ์„ฑํ•ด๋ณด์ž.

Elasticsearch ๋„๋ฉ”์ธ ์ƒ์„ฑ

์ƒˆ ๋„๋ฉ”์ธ ์ƒ์„ฑ ๋ฒ„ํŠผ ๋ˆ„๋ฅธ ํ›„ ์›ํ•˜๋Š” ๊ฒƒ์„ ์„ ํƒํ•œ๋‹ค. ๋‚˜๋Š” ๊ฐœ๋ฐœ ๋ฐ ํ…Œ์ŠคํŠธ๋ฅผ ์„ ํƒํ–ˆ๋‹ค.

์ดํ›„ ๋„๋ฉ”์ธ ์ด๋ฆ„์„ ์ ๋‹นํžˆ ์ง€์ • ํ›„ ๋„คํŠธ์›Œํฌ๋ฅผ ๊ตฌ์„ฑํ•œ๋‹ค. ๋‚˜๋Š” ๋„๋ฉ”์ธ ์ด๋ฆ„์„ pinpoint๋กœ ์ง€์ •ํ•˜์˜€๋‹ค.

๋‚˜๋Š” ๋„คํŠธ์›Œํฌ ๊ตฌ์„ฑ์€ ํผ๋ธ”๋ฆญ ์•ก์„ธ์Šค๋กœ ๊ตฌ์„ฑํ•˜์˜€๊ณ  ์„ธ๋ถ„ํ™”๋œ ์•ก์„ธ์Šค ์ œ์–ด ํ™œ์„ฑํ™” ๊ธฐ๋Šฅ์€ ๋น„ํ™œ์„ฑํ–ˆ๋‹ค.

(์ตœ์†Œํ•œ์˜ ๋ณด์•ˆ์„ ์œ„ํ•ด ์„ธ๋ถ„ํ™”๋œ ์•ก์„ธ์Šค ์ œ์–ด๋Š” ํ™œ์„ฑํ™” ํ•˜๊ณ  ์“ฐ๋Š”๊ฒŒ ์ข‹๋‹ค.)

์ตœ์†Œํ•œ์˜ ๋ณด์•ˆ์„ ์œ„ํ•ด whatismyip.com ์—์„œ ๋‚ด IP๋ฅผ ์ฐพ์€ ํ›„ ํ•ด๋‹น IP๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์•ก์„ธ์Šค ์ •์ฑ…์„ ๊ตฌ์„ฑํ–ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•ด๋†“์œผ๋ฉด ๋‚ด IP๋กœ๋งŒ Elasticsearch์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ดํ›„ ์ตœ์ข… ์ƒ์„ฑ๊นŒ์ง€ ํ•˜๊ณ  ๋‚˜์„œ Elasticsearch ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ๋ชจ๋‘ ํ”„๋กœ๋น„์ €๋‹ ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ์ž.

์ด๋Š” ์•ฝ 10~20๋ถ„ ์ •๋„ ์†Œ์š”๋œ๋‹ค.

Kinesis Firehose ์ƒ์„ฑ

Elasticsearch๋ฅผ ์ƒ์„ฑํ–ˆ์œผ๋‹ˆ ์ด์ œ Kinesis Firehose๋ฅผ ์ƒ์„ฑํ•˜์ž

Kinesis ์„œ๋น„์Šค ๋ฉ”๋‰ด๋กœ ๋“ค์–ด๊ฐ€์„œ Kinesis Firehose๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

์†Œ์Šค๋Š” ๊ทธ๋ƒฅ ๊ธฐ๋ณธ ์„ ํƒ๋ผ์žˆ๋Š” ๊ฒƒ(Direct PUT or other sources) ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค.

Transform source records์™€ Convert record format๋„ ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค.

์ฐธ๊ณ ๋กœ S3์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ ํ›„ AWS Glue ๋“ฑ์„ ํ†ตํ•˜์—ฌ ETL ์ž‘์—… ๋“ฑ์„ ์ˆ˜ํ–‰ ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ฐ์ดํ„ฐ ํฌ๋งท์„ Apache Parquet ๋“ฑ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์ˆ˜ํ–‰ ํ•˜๋Š” ๊ฒƒ์ด ์ตœ์ ํ™”์— ๋„์›€์ด ๋œ๋‹ค. ํ•˜์ง€๋งŒ ์ง€๊ธˆ์€ Elasticsearch๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ฌด๊ฒƒ๋„ ๊ฑด๋“ค์ง€ ๋ง๋„๋ก ํ•˜์ž.

Destination์—์„œ Elasticsearch๋ฅผ ์„ ํƒํ•œ๋‹ค.

Domain์—์„œ๋Š” ์•ž์„œ ์ƒ์„ฑํ•œ Elasticsearch์˜ ๋„๋ฉ”์ธ์„ ์„ ํƒํ•ด ์ค€๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€๋Š” ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค.

๋‚˜๋Š” ์žฌ๋ฏธ ์‚ผ์•„์„œ Index Rotation์„ Daily๋กœ ์„ ํƒํ–ˆ๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ ์ง€์ •ํ•œ Index ๋’ค์— ๋‚ ์งœ๋กœ ๋œ postfix๊ฐ€ ๋ถ™๋Š”๋‹ค. (์˜ˆ: pinpoint-2020-05-18)

๋‚˜์ค‘์— ์šฉ๋Ÿ‰์ด ๊ฝ‰ ์ฐจ๋ฉด ์˜ˆ์ „ ์ธ๋ฑ์Šค๋ฅผ ์ง€์šด๋‹ค๋˜์ง€ ํ•˜๋Š” ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Index Rotation ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

S3 backup์€ Failed records only๋กœ ๋‘๊ณ  ์ ๋‹นํ•œ ๋ฒ„์ผ“์„ ํ•˜๋‚˜ ์„ ํƒํ•œ๋‹ค.

๋‚˜์˜ ๊ฒฝ์šฐ๋Š” Backup S3 bucket prefix๋Š” failed_ ๋กœ ํ–ˆ๋‹ค.

Elasticsearch buffer conditions์€ 1MiB์™€ 60seconds๋กœ ์„ค์ •ํ–ˆ๋‹ค.

์œ„์™€ ๊ฐ™์ด ์„ค์ • ํ•  ๊ฒฝ์šฐ Kinesis Firehose๋กœ ์ „๋‹ฌ๋œ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ 1MiB๊ฐ€ ๋˜๊ฑฐ๋‚˜, 60์ดˆ๊ฐ€ ์ง€๋‚ ๋•Œ ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ Elasticsearch๋กœ ์ „๋‹ฌํ•œ๋‹ค.

๋‚˜๋จธ์ง€๋Š” ๋‹ค ๊ทธ๋Œ€๋กœ ๋‘๊ณ  Permissions ํ•ญ๋ชฉ์—์„œ Create new or choose ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ Firehose โ†’ Elasticsearch ์ „์†ก์„ ์œ„ํ•œ ์ƒˆ๋กœ์šด Role์„ ์ƒ์„ฑํ•œ๋‹ค.

์ด์ œ Create delivery stream ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ Kinesis Firehose๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ƒ์„ฑ๊นŒ์ง€๋Š” ์•ฝ 1๋ถ„์ •๋„ ์†Œ์š” ๋œ๋‹ค.

Pinpoint Event Stream ํ™œ์„ฑํ™”

Amazon Pinpoint โ†’ ์›ํ•˜๋Š” ํ”„๋กœ์ ํŠธ ํด๋ฆญ โ†’ Settings โ†’ Event stream โ†’ Edit โ†’ Stream to Amazon Kinesis์— ์ฒดํฌ

์œ„ ํ™”๋ฉด ์ฒ˜๋Ÿผ ๊ตฌ์„ฑํ•˜์˜€๋‹ค.

์ด์ œ Save ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด,,, ๋“œ๋””์–ด Pinpoint์˜ ๋ชจ๋“  ์ด๋ฒคํŠธ๊ฐ€ Elasticsearch์— ์ €์žฅ์ด ๋œ๋‹ค.

์•„์ง๊นŒ์ง€๋Š” ์•„๋ฌด ์บ ํŽ˜์ธ๋„ ๋ณด๋‚ด์ง€ ๋ง์ž. ์บ ํŽ˜์ธ์„ ๋ณด๋‚ด๊ณ  ๋‚œ ๋’ค์—๋Š” type ์„ค์ •์ด ์—‰ํ€ด๊ณ  ๋งŒ๋‹ค.

Timestamp ์„ค์ •

๊ธฐ๋ณธ์ ์œผ๋กœ Pinpoint๊ฐ€ ์ƒ์„ฑํ•˜๋Š” Event Stream์—๋Š” arrival_timestamp์™€ event_timestamp๊ฐ’์ด ์žˆ๋‹ค. ์ด ์ค‘ ๊ฐ์ข… ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐ ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ’์€ arrival_timestamp๋กœ ์ถ”์ •๋œ๋‹ค. ์ฆ‰ ๋ฐ์ดํ„ฐ๋ฅผ arrival_timestamp ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•ด์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ด๋‹ค.

์•„์‰ฝ๊ฒŒ๋„ ์ด ์ƒํƒœ์—์„œ Kibana๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด.. ์ •๋ ฌ ๊ธฐ๋Šฅ์ด ์ œ๊ณต ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ ์ˆœ์„œ๊ฐ€ ๋งˆ๊ตฌ์žก์ด๋กœ ์—‰์ผœ์ง„์ฑ„๋กœ ์ œ๊ณต๋œ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด arrival_timestamp ๊ฐ’์ด 'date' type ์ด๋ผ๋Š” ๊ฒƒ์„ ๋ฏธ๋ฆฌ ์•Œ๋ ค์ฃผ์ž.

์šฐ์„  AWS Elasticsearch ์„œ๋น„์Šค๋กœ ๋“ค์–ด๊ฐ€์„œ Kibana ์˜†์— ์žˆ๋Š” ๋งํฌ๋ฅผ ํด๋ฆญํ•˜์—ฌ Kibana๋กœ ์ ‘์†ํ•œ๋‹ค.

์ดํ›„ ์™ผ์ชฝ์— ์žˆ๋Š” ๋ฉ”๋‰ด ์ค‘ Dev Tools๋ฅผ ์„ ํƒํ•œ๋‹ค.

Dev Tools๋Š” REST API๋ฅผ ํ†ตํ•ด Elasticsearch์— ๋ช…๋ น์„ ์ˆ˜ํ–‰ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š”๋‹ค.

์ด์ œ ์•„๋ž˜์˜ ๋ช…๋ น์„ ํ†ตํ•ด index template์„ ์ƒ์„ฑํ•˜์ž.

POST _template/default_template
{
  "index_patterns" : [
      "pinpoint*"
    ],
  "order": 1,
  "mappings": {
    "properties": {
      "arrival_timestamp": {
        "type": "date",
        "format": "epoch_millis"
      }
    }
  }
}

"order": 1 ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ๊ฐ€์žฅ ์šฐ์„  ์ˆœ์œ„๊ฐ€ ๋†’๊ฒŒ ์ ์šฉ ๋˜๋Š” index template์ด๋‹ค.

"template": pinpoint* ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ ๋ชจ๋“  pinpoint* index pattern์ด ํ•ด๋‹น index template์˜ ๋Œ€์ƒ์ด ๋œ๋‹ค.

๋ช…๋ น์–ด๋ฅผ ์™ผ์ชฝ์นธ์— ์ž…๋ ฅํ•˜๊ณ  ํ™”์‚ดํ‘œ ๋ชจ์–‘์˜ '์‹คํ–‰' ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ REST API๋ฅผ ์ˆ˜ํ–‰ํ•˜์ž.

์ด์ œ Index Pattern์„ ์„ค์ •ํ•  ์ฐจ๋ก€๋‹ค.

ํ˜„์žฌ๋Š” Elasticsearch์— ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ์—†๊ธฐ ๋•Œ๋ฌธ์— Index Pattern์„ ์„ค์ •ํ•˜๊ณ  ์‹ถ์–ด๋„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋Š” ์•Œ๋ฆผ๋งŒ ๋‚˜์˜จ๋‹ค.

์ด์ œ ์•„๋ฌด ๋ฐ์ดํ„ฐ๋‚˜ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด Pinpoint์—์„œ ์•„๋ฌด ์บ ํŽ˜์ธ์ด๋‚˜ ์ˆ˜ํ–‰ํ•˜์ž. ๋‚˜์˜ ๊ฒฝ์šฐ๋Š” ๊ฐ€์žฅ ์‰ฝ๊ฒŒ Email ์บ ํŽ˜์ธ์„ ์ˆ˜ํ–‰ํ–ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์•ฝ 1~2๋ถ„์ด ์ง€๋‚˜๋ฉด Pinpoint์˜ Event stream ๊ธฐ๋Šฅ์ด Kinesis Firehose๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ธ ํ›„, Elasticsearch๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ–ˆ์„ ๊ฒƒ์ด๋‹ค.

์ œ์ผ ์™ผ์ชฝ ์œ„ Home ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ Home์œผ๋กœ ๊ฐ„ ํ›„, ํ™”๋ฉด์— ๋ณด์ด๋Š” ๋ฒ„ํŠผ ์ค‘ Use Elasticsearch data๋ฅผ ํด๋ฆญํ•œ๋‹ค.

๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌด์‚ฌํžˆ ๋“ค์–ด์™”๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด No Elasticsearch indices match your pattern์— ์ธ๋ฑ์Šค ๋ชฉ๋ก์ด ๋ณด์—ฌ์ง„๋‹ค.

์ธ๋ฑ์Šค ํŒจํ„ด์— pinpoint* ๋ผ๊ณ  ์ž…๋ ฅ ํ›„ Next step ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์ž

๊ทธ๋Ÿฌ๋ฉด Time Filter field name ๋ž€์— ์ฝค๋ณด ๋ฐ•์Šค๊ฐ€ ๋ณด์ผ ๊ฒƒ์ด๋‹ค.

์—ฌ๊ธฐ์„œ arrival_timestamp๋ฅผ ์„ ํƒ ํ›„ Create index pattern ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์ž

์ดํ›„ ํ‘œ์‹œ๋˜๋ฉด ํ™”๋ฉด์—์„œ arrival_timestamp ํ•ญ๋ชฉ์ด date ํƒ€์ž…์œผ๋กœ ์„ค์ •๋ผ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ๋ถ€ํ„ฐ ์“ฐ๊ณ  ์‹ถ์€๋Œ€๋กœ Elasticsearch๋ฅผ ์‚ฌ์šฉํ•˜์ž.

Discover์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ํ‘œ์‹œ ์•ˆ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ์šฐ์ธก ์œ„์˜ Range Filter๊ฐ€ Last 15 minutes๋กœ ๋ผ์žˆ๋Š” ๊ฒฝ์šฐ์— ํ‘œ์‹œ๊ฐ€ ์•ˆ๋œ๋‹ค๊ณ  ์ฐฉ๊ฐํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. ์›ํ•˜๋Š” ํƒ€์ž„๋ผ์ธ์œผ๋กœ ์กฐ์ •ํ•˜์—ฌ ์‚ฌ์šฉํ•˜์ž.

์ถœ์ฒ˜ : https://velog.io/@jakemraz/AWS-Pinpoint-Kinesis-Firehose-Elasticsearch-Event-stream-%ED%99%9C%EC%84%B1%ED%99%94

Last updated