AWS ๊ธฐ์ ๋ธ๋ก๊ทธ
๋ด๋ฅ์ค์ AWS ์๋น์ค๋ฅผ ํ์ฉํ ๊ฒ์ ์์คํ ๊ตฌ์ถ๊ณผ ์ด์ ์ฌ๋ก
์๊ฐ
๋ด๋ฅ์ค(NEWNEX)๋ 2014๋
์ ์ค๋ฆฝ๋ ํจ์
์ด์ปค๋จธ์ค ํ๋ซํผ ๊ธฐ์
์ผ๋ก, IT ๊ธฐ์ ์ ํ์ฉํด ์ปค๋จธ์ค์ ๋ฌผ๋ฅ ์ธํ๋ผ๋ฅผ ํตํฉํ์ฌ โํ๋ฃจ๋ฐฐ์กโ๊ณผ ๊ฐ์ ์ต์ ์ ์ผํ ๊ฒฝํ์ ์ ๊ณตํ๊ณ ์์ต๋๋ค.

ํ์ฌ 1020 ์ฌ์ฑ ํจ์
ํ๋ซํผ โ๋ธ๋๋โ, ๋จ์ฑ ์ผํ ํ๋ซํผ โํ์ด๋ฒโ, ์ฌ์ฑ ๋ธ๋๋ ํจ์
ํ๋ซํผ โ์์ธ์คํ ์ดโ๋ฅผ ์ด์ ์ค์ด๋ฉฐ, ํ๋งค์์๊ฒ ๋ฌผ๋ฅ์ ์ด์์ ์ง์ํ๋ ํตํฉ ์๋น์ค์ธ โํฌํผโ๋ ์ ๊ณตํ๊ณ ์์ต๋๋ค. ๋ด๋ฅ์ค๋ 2024๋
๊ธฐ์ค ๋์ ๊ฑฐ๋์ก 1.8์กฐ ์, ํฌ์ ์ ์น 1,530์ต ์์ ๋ฌ์ฑํ๋ ๋ฑ ๋น ๋ฅด๊ฒ ์ฑ์ฅํ๊ณ ์์ผ๋ฉฐ โNew Thinking Next Moving(์๋ก์ด ์ฌ๊ณ , ๋ค์ ๋จ๊ณ๋ก์ ์์ง์)โ์ด๋ผ๋ ์ฌ๋ช
์๋, โ๋ค์ ์ธ๋์ ์ปค๋จธ์คโ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๋์์์ด ๋์ ํ๊ณ ํ์ ํ๊ณ ์๋ ๋ํ๋ฏผ๊ตญ ๋ํ ์คํํธ์
์
๋๋ค.

๊ฒ์ ์์คํ ๊ตฌ์ถ ๋ฐฐ๊ฒฝ
๋ด๋ฅ์ค์์ ์ด์ํ๋ ํจ์ ํ๋ซํผ์ธ โ๋ธ๋๋โ์ โํ์ด๋ฒโ๋ ๊ธฐ์กด์ SaaS ํํ๋ก ์ ๊ณต๋๋ ํ์ฌ์ ๊ฒ์ ์๋ฃจ์ ์ ์ฌ์ฉํ๊ณ ์์์ต๋๋ค. ์ด๋ ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก JSON ํ์ผ๋ก ์ถ์ถํ์ฌ ๊ฒ์ ์๋ฃจ์ ๊ณผ ์ฐ๊ณํ๊ณ , REST API๋ฅผ ํตํด ๊ฒ์ ์ง์๋ฅผ ์ํํ๋ ๋ฐฉ์์ด์์ต๋๋ค. ์ด๋ฌํ ์ ๊ทผ๋ฒ์ ๋จ์ํ๊ณ ํธ๋ฆฌํ ์ ์ด ์์์ผ๋, ๋๋ ทํ ํ๊ณ์ ์ด ์์์ต๋๋ค.
- ๋น์ฆ๋์ค ๋ฐ ์๊ตฌ์ฌํญ ๋ณํ์ ๋ํ ๋น ๋ฅธ ๋์์ ์ด๋ ค์
๋ํ์ ์ผ๋ก ์ ์ ์ ์ฑ ๋ณ๊ฒฝ์ด ์์ต๋๋ค. ๊ฒ์์ ์ ์ ์ ์ฑ ๊ณผ ๋ฐ์ ํ๊ฒ ์ฐ๊ด๋์ง๋ง, ์ ์ฑ ๋ณ๊ฒฝ ์ ๋ด๋ถ ์์คํ ์๋ ์ฆ์ ๋ฐ์๋๋ ๋ฐ๋ฉด ์ธ๋ถ ์๋ฃจ์ ์๋ ์ฆ๊ฐ์ ์ธ ๋์์ด ์ง์ฐ๋๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. - ํ์ฅ์ฑ ๋ถ์กฑ
์๋ก์ด ์๋น์ค๋ฅผ ์ถ๊ฐํ ๋, ๋น์ฆ๋์ค ํน์ฑ์ ๋น ๋ฅด๊ฒ ์ดํดํ๊ณ ๋๋ฉ์ธ์ ๋ฐ์ํ๊ธฐ ์ํด์๋ ๋ด๋ถ ์ธ๋ ฅ์ ๊ธด๋ฐํ ํ์กฐ๊ฐ ํ์ํ์ง๋ง, ์ธ๋ถ ์๋ฃจ์ ์ฌ์ฉ ์ ์ด ๊ณผ์ ์ด ๋ ์ด๋ ค์ ์ต๋๋ค. - ์ฆ๋ถ ์์ธ ์ฃผ๊ธฐ
ํ๋ฃจ์ ํ ๋ฒ ์ ์ฒด ์์ธ ์ฃผ๊ธฐ๊ฐ ์์๊ณ , 30๋ถ๋ง๋ค ์ถ๊ฐ, ์์ , ์ญ์ ๋ ์ํ๋ค์ ์ฆ๋ถ ์์ธ์ ํตํด ๋ฐ์ํ์ต๋๋ค. ๋๋ฉ์ธ์ ๋ฐ๋ผ 30๋ถ์ ์ฃผ๊ธฐ๋ก ์ถฉ๋ถํ ์ ์์ง๋ง, ํจ์ ์ปค๋จธ์ค ํ๋ซํผ์์๋ ๋น ๋ฅธ ์์ ์ฌํญ ๋ฐ์์ด ํ์ํฉ๋๋ค.
์ด๋ฌํ ๋ฌธ์ ์ ๋ค์ ํด๊ฒฐํ๊ณ ์, ๋ ์ ์ฐํ๊ณ ํจ์จ์ ์ผ๋ก ์์คํ ์ ์ด์ํ๊ธฐ ์ํด ๋ด๋ถ์์ ์ง์ ๊ฒ์ ์์คํ ์ ๊ตฌ์ถํ๊ณ ๊ด๋ฆฌํ๊ธฐ๋ก ํ์ต๋๋ค.
๊ฒ์ ์์คํ ์๋ฃจ์ ๊ฐ์
๋ฐ์ดํฐ๊ฐ ๊ฒ์ ๊ฒฐ๊ณผ๋ก ๋ ธ์ถ๋๊ธฐ๊น์ง๋ ๋๋ถ๋ถ ๋ฐ์ดํฐ ์ถ์ถ โ ๋ฐ์ดํฐ ์์ธ โ ๊ฒ์ ์ง์ ๋ฐ ์๋ต 3๋จ๊ณ๋ก ์ด๋ฃจ์ด ์ง๋๋ค. ์์ผ๋ก ๋ฐ์ดํฐ ์ถ์ถ๊ณผ ๋ฐ์ดํฐ ์์ธ ๊ณผ์ ์ ํธ์์ โ๊ฒ์ ํ์ดํ๋ผ์ธโ์ด๋ผ๊ณ ํํํ๊ฒ ์ต๋๋ค. ์ฆ, ๊ฒ์ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ์ฒด๊ณ์ ์ผ๋ก ์ค๊ณ๋ ํ๋ก์ธ์ค๋ก ์ฃผ๊ธฐ์ ๋ฐ๋ผ ์ด์๋ฉ๋๋ค.
์ด ๊ณผ์ ์์ ์ ํจํ ๋ฐ์ดํฐ๋ฅผ ์ ๊ตํ๊ฒ ์ถ์ถ(Extract)ํ๊ณ , ๋น์ฆ๋์ค ์ธํ ๋ฆฌ์ ์ค๋ฅผ ์ ์ฉํ์ฌ ์ต์ ํ๋ ํํ๋ก ๋ณํ(Transformation)ํฉ๋๋ค. ์ต์ข ์ ์ผ๋ก ์ด๋ ๊ฒ ๊ฐ๊ณต๋ ๋ฐ์ดํฐ๋ ๊ฒ์ ์์คํ ์ ํจ์จ์ ์ผ๋ก ์์ธ(Indexing)๋์ด, ์ ํํ ์ ๋ณด ๊ฒ์์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ์ด๋ฌํ ๊ฒ์ ์์ธ ๊ณผ์ ์ ์ ์ฒด ์์ธ๊ณผ ์ฆ๋ถ ์์ธ ๋ ๊ฐ์ง๋ก ๋๋ ์ ์์ต๋๋ค.
๋ชจ๋ ์ํ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ์ฌ ์๋ก์ด ์ธ๋ฑ์ค๋ก ์์ฑํ๋ ๊ณผ์ ์ โ์ ์ฒด ์์ธโ์ด๋ผ ํ๊ณ , ์ถ๊ฐ, ์์ , ์ญ์ ๋ ์ํ ๋ฐ์ดํฐ๋ฅผ ์ธ๋ฑ์ฑํ๋ ๊ณผ์ ์ โ์ฆ๋ถ ์์ธโ์ด๋ผ๊ณ ํฉ๋๋ค. ๋ด๋ฅ์ค์์๋ ๊ฒ์ ์์คํ ์ ์์ฒด ๊ตฌ์ถํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ํด์ ๊ฐ ์์ธ ๋ฐฉ์ ๋ณ๋ก ๋ชฉํ๋ฅผ ์ค์ ํ์์ต๋๋ค.
1. ์ ์ฒด ์์ธ
๊ฒ์์์ง์ ์ฑ๋ฅ์ ์์ธ ํจ์จ์ฑ์ ํฌ๊ฒ ์ข์ฐ๋๋ฏ๋ก, ํด๋ฌ์คํฐ ํ์ฅ์ด๋ ์ฟผ๋ฆฌ ์ต์ ํ๋ฅผ ํตํด ์ฑ๋ฅ์ ๊ฐ์ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์์ธ์ ์ ๋จ๊ณ์ธ ๋ฐ์ดํฐ ์ถ์ถ ๋ฐ ๋ณํ(ETL, Extract, Transform, Load) ๊ณผ์ ์ด ๊ฐ์ฅ ์ค์ํ ํต์ฌ ๊ณผ์ ๋ก ๋จ์ ์์ต๋๋ค. ๋ธ๋๋์ ๊ฒฝ์ฐ, 200๋ง ๊ฑด ์ด์์ ๋์ฉ๋ ์ํ ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅด๊ฒ ์ถ์ถํ๊ณ , ๋น์ฆ๋์ค ๋ก์ง์ ์ ํํ๊ฒ ๋ฐ์ํ๋ ๋ฐ์ดํฐ ๋ณํ ํ๋ก์ธ์ค๊ฐ ํ์์ ์ ๋๋ค. ์ด๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ ๊ธฐ์ ์ ๋ชฉํ๋ฅผ ์๋ฆฝํ์์ต๋๋ค.
- ์ ์ฐํ ์ค์ผ์ค๋ง ๋ฐ ์คํฌ๋ฆฝํธ ๊ด๋ฆฌ
- ๋ฐ์ดํฐ ๋ณ๋ ฌ ์ฒ๋ฆฌ
- ๊ฐ ETL ๋จ๊ณ์ ๋ช ํํ ์ฑ ์ ๋ถ๋ฆฌ
2. ์ฆ๋ถ ์์ธ
์ด๊ธฐ ์์คํ ๊ตฌ์ถ ์, ๊ธฐ์กด ๊ฒ์ ์์คํ ์ ์ฃผ๊ธฐ์ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์ ์งํ๋ ๊ฒ์ด ์ค์ํ ๋ชฉํ์์ต๋๋ค. ์ด๋ฅผ ์ํด ์ ์ฒด ์์ธ๊ณผ ์ฆ๋ถ ์์ธ ํ๋ก์ธ์ค๋ฅผ ๋์ผํ ์ํคํ ์ฒ๋ก ์ค๊ณํ์์ผ๋ฉฐ, ์ ์ฒด ์์ธ์ ํ๋ฃจ์ ํ ๋ฒ, ์ฆ๋ถ ์์ธ์ ์ผ์ ์๊ฐ๋ง๋ค ์คํ๋๋ ๋ฐฉ์์ผ๋ก ์ด์ํ์์ต๋๋ค. ์ดํ ๊ฒ์ ์์คํ ์ด ์์ ํ๋ ํ, ์ฆ๋ถ ์์ธ์ ์ฃผ๊ธฐ๋ฅผ ๋์ฑ ๋จ์ถํด์ผ ํ ํ์์ฑ์ด ๋๋๋์๊ณ , ์์ ํ ์ค์๊ฐ ์์ธ์ ์๋์ง๋ง ์ด ๋จ์์ ์ค ์ค์๊ฐ(Near real-time) ์์ธ ๊ตฌํ์ ์ค๋นํ์์ต๋๋ค. ์ฆ๋ถ ์์ธ์ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅด๊ฒ ์ ์ฉํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ค์๊ฐ์ฑ์ด ๋ฌด์๋ณด๋ค ์ค์ํฉ๋๋ค. ์ด๋ฅผ ์ต์ ํํ๊ธฐ ์ํด ๊ณ ๋ คํด์ผ ํ ๊ธฐ์ ์ ๋ชฉํ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๊ด๋ฆฌ ๋ณต์ก์ฑ์ ์ต์ํ
- ๋ฐ์ดํฐ ์์ธ ์๋ ๊ทน๋ํ
์ด ๋ ๊ฐ์ง ์์ธ ๋ฐฉ์ ๋ชจ๋ ์๋ํ๋ ์ํฌํ๋ก์ ์ฝ๋ ๊ด๋ฆฌ ํจ์จ์ฑ์ ๊ฐํํ์ฌ ์ ์ง ๋ณด์ ํธ์์ฑ์ ๊ทน๋ํํ๊ณ , ๊ด๋ฆฌ ๋ฐ ์์คํ ๋ฆฌ์์ค๋ฅผ ์ต์ ํํ๋ ๊ฒ์ ๋ชฉํ๋ก ๊ฒ์ ์์คํ ์ ์ค๊ณํ์์ต๋๋ค.
์ ์ฒด ์์ธ ๊ฒ์ ํ์ดํ๋ผ์ธ
1. ์ ์ฒด ์์ธ ์ํคํ ์ฒ ๋ฐ ์ํ์ค
| AWS ์๋น์ค | ์ค๋ช |
|---|---|
| Amazon Managed Workflows for Apache Airflow (MWAA) | Amazon MWAA๋ Apache Airflow๋ฅผ ์ํ ๊ด๋ฆฌํ ์๋น์ค๋ก, ์ด ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ฌ์ ์ต์ํ Apache Airflow ํ๋ซํผ์ ์ฌ์ฉํ์ฌ ์ํฌํ๋ก๋ฅผ ์ค์ผ์คํธ๋ ์ด์ ํ ์ ์์ต๋๋ค. ๊ธฐ๋ฐ ์ธํ๋ผ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ์ ์ค๋ ์ด์ ๋ถ๋ด ์์ด ํ์ฅ์ฑ, ๊ฐ์ฉ์ฑ ๋ฐ ๋ณด์์ ๊ฐ์ ํ ์ ์์ต๋๋ค. |
| AWS Glue | AWS Glue๋ ๋ถ์, ๊ธฐ๊ณ ํ์ต(ML) ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์ ์ํด ์ฌ๋ฌ ์์ค์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ํ์, ์ค๋น, ์ด๋ ๋ฐ ํตํฉํ ์ ์๋๋ก ํ๋ ํ์ฅ ๊ฐ๋ฅํ ์๋ฒ๋ฆฌ์ค ๋ฐ์ดํฐ ํตํฉ ์๋น์ค์ ๋๋ค. |
| Amazon Simple Storage Service(Amazon S3) | Amazon Simple Storage Service(Amazon S3)๋ ์ ๊ณ ์ต๊ณ ์์ค์ ํ์ฅ์ฑ, ๋ฐ์ดํฐ ๊ฐ์ฉ์ฑ, ๋ณด์ ๋ฐ ์ฑ๋ฅ์ ์ ๊ณตํ๋ ๊ฐ์ฒด ์คํ ๋ฆฌ์ง ์๋น์ค์ ๋๋ค. |
| Amazon Opensearch Service | Amazon OpenSearch Service๋ ์ ํ๋ฆฌ์ผ์ด์ ๋ชจ๋ํฐ๋ง, ๋ก๊ทธ ๋ถ์, ๊ด์ธก์ฑ ๋ฐ ์น ์ฌ์ดํธ ๊ฒ์๊ณผ ๊ฐ์ ์ฌ์ฉ ์ฌ๋ก์์ ๋น์ฆ๋์ค ๋ฐ ์ด์ ๋ฐ์ดํฐ์ ์ค์๊ฐ ๊ฒ์, ๋ชจ๋ํฐ๋ง ๋ฐ ๋ถ์์ ์์ ํ๊ฒ ์ง์ํฉ๋๋ค. |
๊ตฌ์ฑ๋์ ๋ฐ๋ผ ์ค์ผ์ค๋ง ์คํ๋ถํฐ ์์ธ ์๋ฃ๊น์ง์ ๊ณผ์ ์ ์์๋๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค.
2. ๋ฐ์ดํฐ ์ถ์ถ
- MWAA: ์ค์ ๋ ์ค์ผ์ค์ ๋ฐ๋ผ ๋ฐ์ดํฐ ์ถ์ถ์ ์ํ AWS์ ETL ๋๊ตฌ์ธ Glue Job์ ์คํํฉ๋๋ค.
- Glue: ํ์ฑ ์ํ ์ ๋ณด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค(Amazon Relational Database Service, RDS)์ ์ ์ฅ๋์ด ์์ผ๋ฉฐ, ์ด ๋ฐ์ดํฐ๋ฅผ Apache Spark๋ฅผ ์ฌ์ฉํด ์ถ์ถํฉ๋๋ค.
3. ๋ฐ์ดํฐ ๋ณํ
- Glue: ์ถ์ถ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํ์ผ๋ก ๋น์ฆ๋์ค ๋ก์ง์ ์ ์ฉํ์ฌ, JSON ํํ์ ์นผ๋ผ๋ฐฉ์์ผ๋ก ์ ์ฅํ๋ Apache Parquet ํ์ผ๋ก ๋ณํํฉ๋๋ค.
- S3: ๋ณํ๋ Parquet ํฌ๋งท์ S3 ๋ฒํท์ ์ ์ฅ๋ฉ๋๋ค.
4. ๋ฐ์ดํฐ ์์ธ
- MWAA: ๋ฐ์ดํฐ ์ถ์ถ Glue Job์ด ์ข ๋ฃ๋๋ฉด ํธ๋ฆฌ๊ฑฐ๊ฐ ํ์ฑํ๋์ด ๋ฐ์ดํฐ ์์ธ์ ์ํ Glue Job์ด ์คํ๋ฉ๋๋ค.
- Glue: S3 ๋ฒํท์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด OpenSearch์ Bulk API๋ฅผ ํตํด ์ธ๋ฑ์ฑ ์์ ์ ์ํํฉ๋๋ค.
๐ก์์ ์ํคํ ์ฒ๋ฅผ ์ค๊ณํ ๋์ ๊ณ ๋ ค์ฌํญ๋ค์ ๋ชจ๋ ์ถฉ์กฑ์ํฌ ๋ฟ๋ง ์๋๋ผ, ์๋์ ๊ฐ์ ์ถ๊ฐ์ ์ธ ์ด์ ๋ ์ ๊ณต๋ฉ๋๋ค.
- ์ค์ผ์ค๋ง ๋ฐ ์คํฌ๋ฆฝํธ ๋ณ๊ฒฝ ์ฉ์ด์ฑ
์ค์ผ์ค๋ง๊ณผ ์คํฌ๋ฆฝํธ ๋ณ๊ฒฝ์ด ์ฉ์ดํด์ผ ํฉ๋๋ค. MWAA๋ ์ํฌํ๋ก ๊ด๋ฆฌ ๋๊ตฌ๋ก, ์คํฌ๋ฆฝํธ์์ ์ค์ผ์ค๋ง๊ณผ ํธ๋ฆฌ๊ฑฐ ์ค์ ์ด ๊ฐํธํ๊ฒ ์ด๋ฃจ์ด์ง ์ ์์ต๋๋ค. ์ฝ์ ํ๋ฉด์ ํตํด ๋ชจ๋ Directed Acyclic Graph (DAG) ์์ ์ ์ด๋ ฅ์ ํธ๋ฆฌํ๊ฒ ํ์ธํ ์ ์์ด, ๊ฒ์ ํ์ดํ๋ผ์ธ ๊ด๋ฆฌ์ ์ ํฉํฉ๋๋ค. - ์ํ ์ด๋ ฅ ๋ฐ ๋ก๊ทธ ์ ์ฌ
์ํ ์ด๋ ฅ๊ณผ ๋ก๊ทธ๋ฅผ ์ ์ ํ ๊ธฐ๋กํ๊ณ ๊ด๋ฆฌํ ์ ์์ด์ผ ํฉ๋๋ค. Glue๋ ์ํ ์ด๋ ฅ ํ์ธ์ด ๊ฐ๋ฅํ๋ฉฐ, ETL ์์ ์ ์๋ฒ๋ฆฌ์ค๋ก ์ํํ ์ ์์ด, ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๊ณผ์ ์์ ๋ฐ์ํ๋ ๋ก๊ทธ์ ์ด๋ ฅ์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค. - ์๋ํ
์ ์ฒด ํ๋ก์ธ์ค๋ฅผ ์๋ํํ์ฌ ์ธ์ ์ค๋ฅ๋ฅผ ์ค์ด๊ณ , ์ผ๊ด์ฑ ์๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ๋ณด์ฅํด์ผ ํฉ๋๋ค. MWAA์ Glue๋ ์์ ์ํคํ ์ฒ์์ ํ์ธ๋ ๋ฐ์ ๊ฐ์ด ์๋ํ๋ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ๋ ๋ฐ ํจ๊ณผ์ ์ ๋๋ค. - ๋ฐ์ดํฐ ๋ณ๋ ฌ ์ฒ๋ฆฌ
๋๊ท๋ชจ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์์๋ ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ํจ์จ์ฑ์ ์ต๋ํ์ผ๋ก ๋์ด์ฌ๋ฆฌ๋ ๊ฒ์ด ํต์ฌ์ ๋๋ค. Spark๋ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ ๋ด์์ ์ฒ๋ฆฌํ๋ฉฐ, ์ฌ๋ฌ ๋ ธ๋์ ๋ถ์ฐํ์ฌ ๋ณ๋ ฌ๋ก ์์ ์ ์ํํ ์ ์๊ธฐ ๋๋ฌธ์ ์๋๊ฐ ๋น ๋ฅด๊ณ ์์ ์ฑ๋ ๋ฐ์ด๋ฉ๋๋ค. ํ ์ด๋ธ์ ์ค์บํ ๋ ์ง๋ ฌ ์ฒ๋ฆฌ(serial processing)๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ ํฌ๊ธฐ๊ฐ ์ฆ๊ฐํจ์ ๋ฐ๋ผ ์ฟผ๋ฆฌ ์ฒ๋ฆฌ ์๊ฐ๋ ๊ธธ์ด์ง๊ฒ ๋ฉ๋๋ค. ํนํ ์๋ฐฑ ๊ธฐ๊ฐ๋ฐ์ดํธ(GB) ์ด์์ ๋ฐ์ดํฐ๋ฅผ ์ง๋ ฌ๋ก ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ์๋นํ ์๊ฐ์ด ์์๋ ์ ์์ต๋๋ค. ๋ฐ๋ฉด, Glue์์ Spark๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ๋ณ๋ ฌ๋ก ๋ถ์ฐ ์ฒ๋ฆฌํ๋ฉด ์ฝ์ด ์์ ๋น๋กํด ์ฒ๋ฆฌ ์๊ฐ์ด ํ๊ธฐ์ ์ผ๋ก ๋จ์ถ๋๋ฉฐ, ๋์์ ์์คํ ์ ์์ ์ฑ๋ ๋ณด์ฅ๋ฉ๋๋ค. ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ ๋์ฉ๋ ๋ฐ์ดํฐ ๋ถ์์ ํจ์ฌ ๋น ๋ฅด๊ณ ํจ์จ์ ์ผ๋ก ์ํํ ์ ์๋ ์ค์ํ ๋ฐฉ๋ฒ์ ๋๋ค.
์ด๋ฌํ ์ด์ ๋ก MWAA์ Glue๋ฅผ ์ ํํ๊ฒ ๋์๊ณ ์ด์ฒ๋ผ AWS ๊ด๋ฆฌํ ์๋น์ค๋ฅผ ์ ๊ทน ํ์ฉํจ์ผ๋ก์จ ํจ์จ์ ์ด๊ณ ๊ด๋ฆฌ๊ฐ ์ฉ์ดํ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ ์ ์์์ต๋๋ค. ๋ํ ๋ฐ์ดํฐ ์์ง๋์ด๋ง ๊ด์ ์์ ๊ฐ ํ๋ก์ธ์ค๋ฅผ ๋จ๊ณ์ ์ผ๋ก ๋๋ ๋๋ถ์ ๋ฐ์ดํฐ ํ์ง์ ๋ณด์ฅํ ์ ์์ ๋ฟ๋ง ์๋๋ผ, ํ๋์ ๋จ๊ณ์์ ๋ฌธ์ ๊ฐ ์๊ฒจ๋ ๋ชจ๋ ํ๋ก์ธ์ค๊ฐ ์คํจํ๋ ์ผ์ด ์์ต๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๋จ๊ณ๋ง ๋ค์ ์คํํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
5. ์คํฌ๋ฆฝํธ ์์
์ค์ ์ฌ์ฉํ๊ณ ์๋ ์ฝ๋๋ฅผ ๊ฐ๋ตํํ์ฌ MWAA์ Glue ์คํฌ๋ฆฝํธ ์์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
with DAG(
dag_id="dag_id",
tags=["tag1", "tag2"],
default_args={
'owner': 'brandi',
'start_date': datetime(2023, 9, 12, 13, 0, 0),
'on_failure_callback': slack_alert_bot.alert_fail_message,
'on_success_callback': slack_alert_bot.alert_success_message,
'retries': 1
},
catchup=False,
# cron ๋ฐฉ์์ ์ค์ผ์ค๋ง ์ค์
schedule_interval="0 20 * * SAT"
) as dag:
task = trigger_glue_trigger_job(
group_id='group_1',
job_name="extract_job",
# ํ์ฌ ์์
์ข
๋ฃ ์ ์คํ๋๋ trigger job name
trigger_dag_id="trigger_indexing_job",
script_args={
'--arg_1': '1',
'--arg_2': '2',
'--arg_3': '3'
},
trigger_conf={
'trigger_params_1': '1',
'trigger_params_2': '2'
}
)
task
MWAA DAG ์คํฌ๋ฆฝํธ: cron ๋ฐฉ์์ ์ค์ผ์ค๋ง ์ค์ ๊ณผ ํด๋น ์์ ์ข ๋ฃ ํ ์คํ๋๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ค์ ํฉ๋๋ค.
# ๋ฐ์ดํฐ ๋ณ๋ ฌ์ฒ๋ฆฌ ์ ์ฝ์ด์ฌ ํํฐ์
์๋ฅผ ์ค์ ํ๊ณ ํํฐ์
๋ ๋ ๋์ ๊ธฐ์ค ์ด, ๋ฒ์ ์ค์
_products = _reader.option("dbtable", "์คํค๋ง.ํ
์ด๋ธ๋ช
") \
.option("numPartitions", 10) \
.option("partitionColumn", "id") \
.option("lowerBound", _lower_bound) \
.option("upperBound", _upper_bound) \
.load() \
.select(
col("ID"),
col("NAME"),
col("DISPLAY_TYPE")
)
# ๋น์ฆ๋์ค ๋ก์ง์ ์ถ๊ฐํ ๋ฐ์ดํฐ ๋ณํ
_product_df = _products \
.select(
col("ID").cast(StringType()).alias("id"),
col("NAME").alias("product_name"),
when(col("DISPLAY_TYPE") == '1', True).otherwise(False).alias("is_display") \
# ํํฐ์
๋ ์ค์
_product_df.repartition(128).write.mode('overwrite').parquet(_output_path)
์ถ์ถ(Extract) Glue ์คํฌ๋ฆฝํธ: ์์ฒ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ฌ ๋ ํํฐ์ ์ ์ค์ ํ์ฌ ๋ฐ์ดํฐ ๋ณ๋ ฌ ์ฒ๋ฆฌํ๊ณ , ๋ฐ์ดํฐ ๋ณํ ํ ๋ฐ์ดํฐ ํ๋ ์(DataFrame)์ ์์ฑํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ ํ๋ ์์ 128๊ฐ๋ก ํํฐ์ ๋ํ์ฌ S3 ์ถ๋ ฅ ๊ฒฝ๋ก(output path)์ ์ ์ฅํฉ๋๋ค.
_products.rdd.repartition(300)
.mapPartitions(convert_to_json)
.coalesce(1)
.foreachPartition(partial(bulkApi_์ ์ก_๋ฉ์๋, host=๊ฒ์์์ง_ํธ์คํธ, index=์ธ๋ฑ์ค๋ช
))
์์ธ(Indexing) Glue ์คํฌ๋ฆฝํธ: ๋ฐ์ดํฐ ํ๋ ์์ RDD (Resilient Distributed Dataset)๋ก ๋ณํ ํ 300๊ฐ์ ํํฐ์ ์ผ๋ก ๋ถํ ํ์ฌ OpenSearch์ ๋ฒํฌ๋ก ์ธ๋ฑ์ฑ ์งํํฉ๋๋ค.
์์ ์คํฌ๋ฆฝํธ๋ฅผ ๊ฐ๋จํ ์ดํด๋ณด๋ฉด, MWAA DAG ์คํฌ๋ฆฝํธ์์ ์ค์ผ์ค๋ฌ์ ์์ (task)์ ์ง์ ํ ์ ์๋ค๋ ์ ์ ํ์ธํ ์ ์์ต๋๋ค. ๋ํ, ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ธ ๋ Glue์์ Spark๋ฅผ ํ์ฉํด ๋ฐ์ดํฐ ํํฐ์ ๋์ ์ํํ์ฌ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ต์ ํํ ์ ์์ต๋๋ค. ์ธ๋ฑ์ฑ ๋จ๊ณ์์๋ ๊ฒ์์์ง ํด๋ฌ์คํฐ์ ์ฌ์์ ๋ง์ถฐ ๋ฆฌํํฐ์ ๋(repartitioning) ํ๋ผ๋ฏธํฐ๋ฅผ ์กฐ์ ํ์ฌ ๋ฒํฌ ์ธ๋ฑ์ฑ ์์ ์ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
6. ์ฝ์ ํ๋ฉด ์์

Airflow ์ฝ์ ํ๋ฉด โ DAG๋ค์ด ๊ฐ๊ฐ์ ์์
์ผ๋ก ๋์ด๋์ด ํ๋์ ํ์
๊ฐ๋ฅ
Glue ์ฝ์ ํ๋ฉด โ ๊ฐ ์์ ๋ณ ์ํ์ด๋ ฅ๊ณผ ๋ก๊ทธ ํ์ธ ๊ฐ๋ฅ
์ฆ๋ถ ์์ธ ๊ฒ์ ํ์ดํ๋ผ์ธ
์ฆ๋ถ ์์ธ์ ํต์ฌ ๊ณผ์ ์ธ ์ค์๊ฐ์ฑ์ ๋ฐ์ํ๊ธฐ ์ํด ์ ํ๋ฆฌ์ผ์ด์ ์๋ฆผ ์๋น์ค์ธ Amazon Simple Notification Service (SNS)์ ๋ฉ์์ง ํ ์๋น์ค์ธ Amazon Simple Queue Service (SQS)๋ฅผ ์ ํํ์ต๋๋ค. ์ด๋ฏธ ๋์ ๋ ์์คํ ์ด์ด์ ์ถ๊ฐ ๋น์ฉ์ด ๋ค์ง ์๊ณ , ๊ด๋ฆฌ ํฌ์ธํธ๊ฐ ์ ์ด ๋น์ฉ๊ณผ ๋ฆฌ์์ค๋ฅผ ๋ชจ๋ ์ ์ฝํ ์ ์๋ค๋ ํฐ ์ฅ์ ์ด ์์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ํ, SQS ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋๋ง๋ค AWS Lambda๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋๋ก ์ค์ ํด ๋ฐ์ดํฐ ์ถ์ถ๊ณผ ์์ธ์ ํ ๋ฒ์ ์ฒ๋ฆฌํ ์ ์๋๋ก ๊ตฌ์ฑํ์ต๋๋ค.
์ฆ๋ถ ์์ธ ์ํคํ ์ฒ
| AWS ์๋น์ค | ์ค๋ช |
|---|---|
| Amazon Simple Notification Service (SNS) | Amazon Simple Notification Service (SNS)๋ A2A์ A2P์ ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ์๋ฆผ์ ์ ์กํฉ๋๋ค. A2A๋ ๋ถ์ฐ๋ ์์คํ , ๋ง์ดํฌ๋ก์๋น์ค ๋ฐ ์ด๋ฒคํธ ์ค์ฌ์ ์๋ฒ๋ฆฌ์ค ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ์ ์ฒ๋ฆฌ๋์ด ๋ง์ ํธ์ ๊ธฐ๋ฐ์ ๋ค๋๋ค ๋ฉ์์ง์ ์ ๊ณตํฉ๋๋ค. A2P ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด SMS ํ ์คํธ, ํธ์ ์๋ฆผ, ์ด๋ฉ์ผ์ ํตํด ๊ณ ๊ฐ์๊ฒ ๋ฉ์์ง๋ฅผ ์ ์กํ ์ ์์ต๋๋ค. |
| Amazon Simple Queue Service (SQS) | Amazon Simple Queue Service (SQS)๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ์์ง ์์ค์ ์ฐ๋ คํ๊ฑฐ๋ ๋ค๋ฅธ ์๋น์ค๋ฅผ ์ ๊ณตํ ํ์ ์์ด ์ํํธ์จ์ด ๊ตฌ์ฑ ์์ ๊ฐ์ ์ด๋ค ๋ณผ๋ฅจ์ ๋ฉ์์ง๋ ์ ์ก, ์ ์ฅ ๋ฐ ์์ ํ ์ ์์ต๋๋ค. |
| AWS Lambda | AWS Lambda๋ ์ด๋ฒคํธ์ ๋ํ ์๋ต์ผ๋ก ์ฝ๋๋ฅผ ์คํํ๊ณ ์ปดํจํ ๋ฆฌ์์ค๋ฅผ ์๋์ผ๋ก ๊ด๋ฆฌํ๋ ์ปดํจํ ์๋น์ค๋ก, ์์ด๋์ด๋ฅผ ์ต์ ํ๋ก๋์ ์๋ฒ๋ฆฌ์ค ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ์ ํํ๋ ๊ฐ์ฅ ๋น ๋ฅธ ๋ฐฉ๋ฒ์ ๋๋ค. |
์ด์ ๊ฐ ์ํ์ค๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉฐ ๊ณผ์ ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ฆ๋ถ ์์ธ ์ํ์ค: ์ํ๋ณ๊ฒฝ ์ด๋ฒคํธ ๋ฐ์ โ SNS ์ด๋ฒคํธ ๊ฒ์โ SQS ํ ์ถ๊ฐ โ Lambda ์คํ
๋ฐ์ดํฐ ์ถ์ถ
- SNS, SQS
๋ณ๊ฒฝ๋ ์ํ ๋ฒํธ๊ฐ SQS์ ๋ฉ์์ง ํ ์ด๋ฒคํธ ํํ๋ก ์ถ๊ฐ๋ฉ๋๋ค. - Lambda
ํ์ ์ถ๊ฐ๋ ๋ณ๊ฒฝ๋ ์ํ ๋ฒํธ๋ฅผ ๊ฐ์งํ์ฌ ์คํ๋ฉ๋๋ค. Lambda ํจ์์์ RDS์ ์ฟผ๋ฆฌ๋ฅผ ์คํํด ํด๋น ์ํ ๋ฒํธ์ ๋ํ ์ ๋ณด๋ฅผ ์ฝ์ด์ต๋๋ค. Python๊ณผ Pandas๋ฅผ ์ฌ์ฉํด ์ถ์ถ๋ ์ ๋ณด๋ก ๋ฐ์ดํฐํ๋ ์์ ์์ฑํฉ๋๋ค.
๋ฐ์ดํฐ ์์ธ
- Lambda
์์ฑ๋ ๋ฐ์ดํฐํ๋ ์์ OpenSearch์ Bulk API๋ก ์ ๋ฌํด ์์ธ ์์ ์ ์ํํฉ๋๋ค.
์ด ๊ตฌ์ฑ์์ ๋ช ๊ฐ์ง ์ค์ํ ๊ณ ๋ ค ์ฌํญ์ด ์์ต๋๋ค.
- ๋ณ๊ฒฝ ๋ฐ์ดํฐ๊ฐ ์์ฒ ๊ฑด ์ด์ ๋ฐ์ํ๋ ๊ฒฝ์ฐ
- Lambda ํจ์์ ๋์ ์คํ ๋ฌธ์
๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๊ฐ ๋๋์ผ๋ก ๋ฐ์ํ๊ฑฐ๋, Lambda ํจ์์ ๋์ ์คํ ์์ฒญ์ด ๊ณผ๋ํ๊ฒ ๋ง์์ง ๊ฒฝ์ฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๊ณผ๋ถํ๋์ด ๋๋์ ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ด๋ ค์์ง ์ ์์ต๋๋ค. ํนํ ๋ณ๊ฒฝ ๋ฐ์ดํฐ๊ฐ ์ฒ ๋จ์ ์ด์์ผ๋ก ์ฆ๊ฐํ๋ ๊ฒฝ์ฐ, ๊ธฐ์กด์ ๊ตฌ์กฐ๋ณด๋ค๋ CDC(Change Data Capture) ๋ฐฉ์์ ์ฌ์ฉํด ์์ธ์ ๊ตฌ์ฑํ๋ ๊ฒ์ด ๋ ์ ํฉํฉ๋๋ค. ๋ธ๋๋๋ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Lambda ํจ์ ๋ด์์ ๋ฉ์์งํ ์ด๋ฒคํธ๋ฅผ ์ฒญํฌ ๋จ์๋ก ๋ถํ (chunking)ํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ์ ์กํ๋๋ก ์ค๊ณํ์ผ๋ฉฐ, ๋์์ Lambda์ ๋์ ์คํ ์ต์
์ ์กฐ์ ํ์ฌ ์ด์๋ฅผ ํด๊ฒฐํ ์ ์์์ต๋๋ค.
์ฆ๋ถ ์์ธ ์ํคํ
์ฒ๋ฅผ ๊ณ ๋ํํ๋ฉด์, ๊ธฐ์กด 30๋ถ์ด์๋ ์ฃผ๊ธฐ๋ฅผ 1๋ถ ์ด๋ด๋ก ์ค์ด๋ ์ฑ๊ณผ๋ฅผ ๋ฌ์ฑํ๊ณ Lambda ๋์
์ ํตํด ์๋ฒ๋ฆฌ์ค(serverless) ๊ตฌ์กฐ์ ์ฅ์ ์ ํ์ฉํ์ฌ ์ธํ๋ผ ๊ด๋ฆฌ ๋ถ๋ด์ ์ค์ด๊ณ , ๋น ๋ฅธ ์ฒ๋ฆฌ์ ์ด์ ํจ์จ์ฑ์ ๊ทน๋ํํ ์ ์์์ต๋๋ค. ์ฃผ๊ธฐ๊ฐ ๋จ์ถ๋จ์ ๋ฐ๋ผ ๊ฒ์์์ง์ ํ์ฉ ๋ฒ์๋ ๋จ์ํ ๊ฒ์ ๋ฉ๋ด๋ฅผ ๋์ด ๋ค์ํ ์์ญ์ผ๋ก ํ์ฅ๋์์ต๋๋ค.
์ด์ ์๋ ๊ฒ์ ๊ธฐ๋ฅ์์๋ง ์ฌ์ฉ๋๋ ๊ฒ์์์ง์ด ์ด์ ๋ ์ฌ๋ฌ ๊ธฐ๋ฅ์์ ํต์ฌ์ ์ธ ์ญํ ์ ๋ด๋นํ๊ฒ ๋์์ต๋๋ค. ์ค์๊ฐ์ฑ์ ๊ฐ์ถ๊ฒ ๋๋ฉด์ ๋จ์ํ ๊ฒ์ ๋ฉ๋ด๋ฟ๋ง ์๋๋ผ, ์นดํ
๊ณ ๋ฆฌ ํ์ด์ง์๋ ๊ฒ์์์ง์ ๋์
ํด ์ฑ๋ฅ์ ํฅ์์ํค๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ถ๋ด์ ์ค์ด๋ ์ค์ํ ๊ฐ์ ์ ์ด๋ฃฐ ์ ์์์ต๋๋ค.
๊ฒ์ API
์ง๊ธ๊น์ง๋ ๋ฐ์ดํฐ ์ถ์ถ๊ณผ ์์ธ์ ๋ํ ๊ฒ์ ํ์ดํ๋ผ์ธ์ ์ํคํ ์ฒ๋ง ๊ธฐ์ ํ์์ต๋๋ค. ํ์ง๋ง ๊ฒ์ ์์คํ ์ ์ฌ๊ธฐ์ ๋๋์ง ์๊ณ ๊ฒ์ ์ง์ ๋ฐ ๊ฒฐ๊ณผ ๋ฐํ ๊ณผ์ ๊น์ง ํฌํจํด์ผ ์์ฑ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๊ฒ์์์ง(e.g., Opensearch)๋ค์ ์์ง์ ์ง์ ์ฟผ๋ฆฌ๋ฅผ ์์ฒญํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ ๋ฐฉ์์ผ๋ก ์ด์๋ฉ๋๋ค.
๊ฒ์์์ง์ ์ง์ ์ฟผ๋ฆฌ๋ฅผ ์์ฒญํ๋ ๋ฐฉ์์ ์ฌ์ฉํ ์๋ ์์ง๋ง, ์ด ๋ฐฉ์์๋ ํ ๊ฐ์ง ํฐ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ์์ธ ํ๋๋ ์๊ตฌ ์ฌํญ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๊ฒ์์์ง์ ์ฌ์ฉํ๋ ๋ชจ๋ ํ์ด ๊ฐ๊ฐ ์ฟผ๋ฆฌ๋ฅผ ์์ ํด์ผ ํ๋ค๋ ์ ์ด์์ต๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, ๊ฒ์ API๋ฅผ ๊ฐ๋ฐํ๊ฒ ๋์์ต๋๋ค. ๊ฒ์ API๋ฅผ ๋์ ํ๋ฉด์ ์ป๊ฒ ๋ ์ฅ์ ์ ๋งค์ฐ ํฝ๋๋ค. ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ์ถ์ํํ์ฌ ์ ๊ณตํจ์ผ๋ก์จ ์ฌ์ฉ์์ ํธ๋ฆฌ์ฑ์ด ๊ฐํ๋์๊ณ , ์์คํ ํ์ฅ์ฑ๋ ํ๋ณดํ ์ ์์์ต๋๋ค. ๋ํ ๊ฒ์์์ง์ ๋ณ๊ฒฝํด๋ ๊ฒ์ API์ ํด๋ผ์ด์ธํธ๋ง ๋ณ๊ฒฝํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๊ฐ ์ด๋ฅผ ์ธ์งํ๊ฑฐ๋ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ ํ์๊ฐ ์์ต๋๋ค.
๊ฒ์์์ง ์ฟผ๋ฆฌ vs ์ถ์ํ๋ ๊ฒ์ API
{
"from": 0,
"size": 10,
"sort": [
{
"time": "desc"
},
"_score"
],
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "์ํผ์ค",
"fields": [
"index.text",
"index.keyword"
],
"operator": "and"
}
}
],
"filter": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match": {
"category_id": "1"
}
},
{
"match": {
"category_id": "2"
}
}
],
"minimum_should_match": 1
}
},
{
"range" : {
"price": {
"gte": 1000,
"lt": 20000
}
}
},
{
"match": {
"id": "11111"
}
}
]
}
}
}
}
}
๊ฒ์ ์ฟผ๋ฆฌ โ ๊น์ด(depth)๊ฐ ๊น๊ณ ๋ณต์ก
{
"from" : 0,
"size" : 10,
"query": "์ํผ์ค",
"filter" : {
"category": {
"id" : ["1", "2"]
},
"id" : "11111",
"price" : {
"min" : 1000,
"max" : 20000
}
},
"sort" : "time"
}
์ถ์ํ๋ ๊ฒ์ API โ ๊ฒ์ API ํ๋ผ๋ฏธํฐ๊ฐ ์ถ์ํ๋์ด ์ฌ์ฉ์์ ํธ๋ฆฌ์ฑ ์ฆ๋
๋๋ถ๋ถ์ ๊ฒ์์์ง์ ์ธ์ด๋ณ SDK๋ฅผ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ ์์ ๋ ๋น๊ต์ ์์ํฉ๋๋ค. ์ด๋ก์จ ๊ฒ์ API ๊ฐ๋ฐ์ด ์๋ฃ๋จ์ ๋ฐ๋ผ, ์ ์ฒด ๊ฒ์ ์์คํ ๊ตฌ์ถ์ด ์์ฑ๋์์ต๋๋ค.
๋ชจ๋ํฐ๋ง
๊ฒ์ ํ์ดํ๋ผ์ธ์ด ๋ชจ๋ ์๋ํ๋์์ง๋ง, ์ด์ ์ค์๋ ํญ์ ์๊ธฐ์น ์์ ์ํฉ์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๊ธฐ๋ฅ ๊ฐ์ ๊ณผ ๋ฌธ์ ํด๊ฒฐ์ ์ํด ๋ชจ๋ํฐ๋ง์ด ํ์์ ์
๋๋ค.
๊ทธ๋์, ๊ฒ์ ์์คํ
์ ๋ชจ๋ ์๋น์ค๋ฅผ AWS ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถํ์ฌ ๋ชจ๋ํฐ๋ง์ ์ฉ์ดํ๊ฒ ํ๊ณ , ์ด์ ํ์์ด ๋ฐ์ํ ๊ฒฝ์ฐ ๋น ๋ฅด๊ฒ ์ธ์ํ ์ ์๋๋ก ๋ชจ๋ ์๋ฆผ์ Slack์ผ๋ก ํตํฉํ์ฌ ์์ ํ๋๋ก ์ค์ ํ์ต๋๋ค.
๊ฒ์ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ
์ ์ฒด ์์ธ: MWAA๋ ์ํฌํ๋ก์ฐ ๊ด๋ฆฌ ์๋น์ค์ด๊ธฐ ๋๋ฌธ์, ์คํ ์ค์ธ ์์
์ ์ด์์ด ๋ฐ์ํ๋ฉด ์ด๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค. ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ, MWAA์ DAG ์คํฌ๋ฆฝํธ์ Slack์ ์ฐ๊ฒฐํด ๋๋ฉด, ์์
์ด ์ ์์ ์ผ๋ก ์ข
๋ฃ๋์ง ์์์ ๋ ์ง์ ํ ๋ฌธ๊ตฌ๋ก ์๋ฆผ์ ์ ์กํ ์ ์์ต๋๋ค.
์ฆ๋ถ ์์ธ: Lambda ํจ์์์๋ Slack๊ณผ ์ฐ๋ํ ์ ์์ผ๋ฉฐ, ๋๋ค ํจ์๊ฐ ์ ์ ๋๋ ์ค๋ฅ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค. ์ค๋ฅ ๋ฐ์ ์, ์คํฌ๋ฆฝํธ์์ ์ง์ ๋ Slack์ผ๋ก ์๋ฆผ์ ์ก์ ํ ์ ์์ต๋๋ค.

Glue Job ์คํจ๋ฅผ ๊ฒฝ๊ณ ํ๋ Slack ์๋ฆผ ๋ด
๊ฒ์์์ง ํด๋ฌ์คํฐ ์ํ ๋ฐ ๊ฒ์ API
Datadog: Datadog์ AWS ๊ด๋ฆฌํ ์๋น์ค์ ์ํ๋ฅผ ์ฐ๋ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๊ฒ์ ์ง์๊ฐ ์ ์์ ์ผ๋ก ๋ค์ด์ค๋์ง ํ์ธํ ์ ์๋ ์ค์ ์ ํตํด, ๋ฌธ์ ๋ฐ์ ์ฌ๋ถ๋ฅผ ๋ชจ๋ํฐ๋งํ ์ ์์ต๋๋ค.

์ด๋ ๊ฒ ๋ชจ๋ํฐ๋ง๊ณผ ์ด์ ๋ฐ์ ์ ๊ฐ์ง ๋ฐ ๋์์ด ํธ๋ฆฌํ๊ฒ ์ค์ ๋์ด, Slack ๋ฉ์ ์ ๋ฅผ ํตํด ๋ฌธ์ ๋ฅผ ๋น ๋ฅด๊ฒ ์ธ์ํ๊ณ ์กฐ์นํ ์ ์์ต๋๋ค.
ํด๋ผ์ฐ๋ vs ์จํ๋ ๋ฏธ์ค
์์ ํด๋ผ์ฐ๋ ํ๊ฒฝ์์์ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ, ๊ฒ์ API, ๋ชจ๋ํฐ๋ง์ ํฌํจํ ๊ฒ์ ํ์ดํ๋ผ์ธ์ ์ํคํ
์ฒ๋ฅผ ์ดํด๋ณด์์ต๋๋ค. ์ด ์ค, ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ ๊ตฌ์ฑ ์ ์จํ๋ ๋ฏธ์ค๋ก๋ง ๊ตฌ์ถํ์ ๊ฒฝ์ฐ๋ฅผ ๋น๊ตํด ๋ณด๊ฒ ์ต๋๋ค.

AWS ๊ธฐ๋ฐ์์์ ๊ฒ์ ํ์ดํ๋ผ์ธ

์จํ๋ ๋ฏธ์ค ํ๊ฒฝ์์์ ๊ฒ์ ํ์ดํ๋ผ์ธ
์จํ๋ ๋ฏธ์ค ํ๊ฒฝ์์์ ๊ฒ์ ํ์ดํ๋ผ์ธ ์ํคํ ์ฒ ์์ฒด๋ ๊ฐ๋จํด ๋ณด์ด์ง๋ง, ์ค์ ๋ก๋ ์๋นํ ๋ ธ๋๋ ฅ์ด ํ์ํฉ๋๋ค. ๋ฐ์ดํฐ ์ถ์ถ ๋ฐ ๋ณํ์ Spring Batch๋ก ์งํํ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค
100GB ์ด์์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ ๋์ Spring Batch๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ง์์ ์ผ๋ก ์ฐ๊ฒฐ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฐฐ์น ์์
์ ์๊ฐ์ ์กฐ์ ํ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์์ ๊ณ ๋ คํ๋ ๋ฑ์ ์ถ๊ฐ์ ์ธ ๊ด๋ฆฌ๊ฐ ํ์ํฉ๋๋ค.
๐ก Spark๋ฅผ ํ์ฉํ๋ฉด ๋ชจ๋ ํ
์ด๋ธ์ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆฐ ํ ์ฒ๋ฆฌํ ์ ์์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ถ๋ด์ ์ค์ผ ์ ์์ต๋๋ค.
Spring Batch
๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ ๋๋ถ๋ถ์ ์์ ์ด Spring Batch์์ ์ํ๋ฉ๋๋ค. ์ค์ผ์ค๋ฌ ์ค์ , ๋ฐ์ดํฐ ์กฐํ, ๋ฐ์ดํฐ ํ์ฑ, ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ, ๊ฒ์์์ง ์ธ๋ฑ์ฑ ๋ฑ์ด ํฌํจ๋ฉ๋๋ค. ๊ฐ๋จํ ์์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
@Component
public class BatchScheduler {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job indexUserJob;
// ๋งค์ผ ์๋ฒฝ 1์์ ์คํ๋๋ ์ค์ผ์ค๋ง ์ค์ (CRON ํํ์)
@Scheduled(cron = "0 0 1 * * ?")
public void runBatchJob() throws Exception {
JobParameters params = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.toJobParameters();
jobLauncher.run(indexUserJob, params);
}
}
cron ํ์์ผ๋ก ์ค์ผ์ค๋ง์ ์ค์ ํฉ๋๋ค.
@Configuration
public class BatchConfig {
@Bean
public JdbcCursorItemReader<Product> reader(DataSource dataSource) {
return new JdbcCursorItemReaderBuilder<Product>()
.name("productItemReader")
.dataSource(dataSource)
.sql("SELECT id, name FROM products")
.rowMapper((rs, rowNum) -> {
Product product = new Product();
product.setId(rs.getLong("id"));
product.setName(rs.getString("name"));
return product;
})
.build();
}
}
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํ(Product) ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ต๋๋ค. ๋ฐ์ดํฐ ์ถ์ถ ๊ณผ์ ์ ๋๋ค.
public class ProductProcessor implements ItemProcessor<Product, Product> {
@Override
public Product process(Product product) throws Exception {
// ์ถ๊ฐ์ ์ธ ํ์ฑ์ด๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ก์ง์ ์ฌ๊ธฐ์ ์์ฑ
return product;
}
}
๋ฐ์ดํฐ๋ฅผ ๋ณํํ๋ ์ญํ ์ ํฉ๋๋ค.
@Component
public class ElasticsearchItemWriter implements ItemWriter<Product> {
@Autowired
private RestHighLevelClient client;
private static final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void write(List<? extends Product> items) throws Exception {
for (Product product : items) {
IndexRequest request = new IndexRequest("products_index")
.id(product.getId().toString())
.source(objectMapper.writeValueAsString(product),
XContentType.JSON);
client.index(request, RequestOptions.DEFAULT);
}
}
}
๋ณํํ ๋ฐ์ดํฐ๋ฅผ elasticsearch์ ์ธ๋ฑ์ฑ ํฉ๋๋ค.
@Configuration
@EnableBatchProcessing
public class BatchJobConfig {
@Bean
public Job indexProductJob(JobBuilderFactory jobs, Step step1) {
return jobs.get("indexProductJob")
.incrementer(new RunIdIncrementer())
.flow(step1)
.end()
.build();
}
@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
JdbcCursorItemReader<Product> reader,
ProductProcessor processor,
ElasticsearchItemWriter writer) {
return stepBuilderFactory.get("step1")
.<Product, Product>chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
}
๋ฐฐ์น ์์ ๊ณผ ์คํ ์ ์ ์ํฉ๋๋ค. ์์ ์ ์ํ ํด๋์ค๋ค์ ์ฐ๊ฒฐํ์ฌ ์ถ์ถ-๋ณํ-์์ธ์ ์ฒ๋ฆฌํฉ๋๋ค.
์์ฃผ ๋จ์ํ ๊ธฐ๋ณธ ์ฝ๋์์๋ ๋ถ๊ตฌํ๊ณ ๊ณ ๋ คํด์ผ ํ ์์๋ค์ด ๋ง์ต๋๋ค. ์์ ์ฝ๋์๋ ์์ฑ๋์ง ์์์ง๋ง, ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋ฉํฐ์ค๋ ๋ฉ ๊ตฌ์ฑ์ ์ถ๊ฐํด์ผ ํ๋ฉฐ, ํธ๋์ญ์ ๊ด๋ฆฌ์ ์ฒญํฌ ํฌ๊ธฐ ์ค์ ๋ ์ค์ํ ๋ถ๋ถ์ ๋๋ค. ์์ ๋ณ๋ก ์ฒ ์ ํ ์์ธ ์ฒ๋ฆฌ๋ฅผ ์ํํ๊ณ , ์ค๋ฅ ๋ฐ์ ์ ๋ฌธ์ ๋ฐ์ ๋จ๊ณ์ ์์ธ์ ์ ํํ ํ์ ํ ์ ์๋๋ก ๋ก๊ทธ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๊ฒ๋ ํ์์ ์ ๋๋ค. ๋ชจ๋ ๋จ๊ณ๊ฐ Spring Batch์์ ์คํ๋๋ค ๋ณด๋, ๋ฐ์ดํฐ ์ถ์ถ ๋ก์ง๊ณผ ๋น์ฆ๋์ค ๋ก์ง์ ๋ช ํํ๊ฒ ๋ถ๋ฆฌํ๊ธฐ๊ฐ ์ด๋ ต์ต๋๋ค. ๋ํ, ์๊ตฌ์ฌํญ์ด ๋ณ๊ฒฝ๋๋ฉด ๋น๋์ ๋ฐฐํฌ ๊ณผ์ ์ ๋ค์ ๊ฑฐ์ณ์ผ ํ๋ฉฐ, ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ๋ชจ๋ ์์ ์ ์ฒ์๋ถํฐ ๋ค์ ์๋ํด์ผ ํ๋ ๋ฌธ์ ๋ ๋ฐ์ํ ์ ์์ต๋๋ค. ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ฝ๋๊ฐ ๋ธ๋๋ฐ์คํ๋ ๊ฐ๋ฅ์ฑ๋ ์์ผ๋ฉฐ, ๊ด๋ฆฌํด์ผ ํ ์์ ์ด 1n๊ฐ ์ด์์ผ๋ก ๋์ด๋๋ฉด ์ถ๊ฐ์ ์ธ ์ธ๋ ฅ๊ณผ ๋ฆฌ์์ค๊ฐ ํ์ํ ๊ฒ์ ๋๋ค.
MWAA์ Glue๋ฅผ ์ฌ์ฉํ๋ฉด ์ค์ผ์ค๋ง๊ณผ ์์ ์ ์์ ํ ๋ถ๋ฆฌํ ์ ์์ต๋๋ค. ๋ํ ๋ฐ์ดํฐ ์กฐํ์ ๋น์ฆ๋์ค ๋ก์ง์ ๊ฐ๊ฐ ๋ ๋ฆฝ์ ์ธ ์์ ์ผ๋ก ๋ถ๋ฆฌํ๋ฉด ๋ณต์ก๋๊ฐ ์ค์ด๋ค๊ณ ์ฝ๋๊ฐ ๊ฐ์ํ๋ฉ๋๋ค. ์ฝ์ ํ๋ฉด์์ ์์ ์ ํ์ธํ ์ ์๊ธฐ ๋๋ฌธ์ ์์ ์ ์๊ฐ ํ์ฅ๋์ด๋ ์ธ๋ ฅ์ด ํ์ํ์ง ์์ต๋๋ค.
์จํ๋ ๋ฏธ์ค ๊ฒ์์์ง
๋ง์คํฐ ๋ ธ๋, ๋ฐ์ดํฐ ๋ ธ๋, ์ฝ๋๋ค์ดํฐ ๋ ธ๋ ๋ฑ ํด๋ฌ์คํฐ์ ๋ ธ๋ ์ต์ ์ ์ง์ ์ค์ ํด์ผ ํฉ๋๋ค. ๊ธฐ๋ณธ ์ฝ์ ๋๊ตฌ๊ฐ ์๊ธฐ ๋๋ฌธ์ Kibana์์ ๋ชจ๋ ์ต์ ๊ณผ ๋์๋ณด๋๋ฅผ ๊ตฌ์ฑํด์ผ ํฉ๋๋ค. ๊ด๋ฆฌํ ๊ฒ์์์ง ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋ฌ์คํฐ ์ฑ๋ฅ์ ๋ชจ๋ํฐ๋งํ๊ณ ์๋์ผ๋ก ์ต์ ํํ์ฌ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์๋ฐฉํ ์ ์์ต๋๋ค. ๋ํ, ์ ๊ทธ๋ ์ด๋์ ํจ์น๋ฅผ ์๋์ผ๋ก ์งํํ์ฌ ๊ด๋ฆฌ ๋ถ๋ด์ ์ค์ฌ์ค๋๋ค.
์ฆ, ์จํ๋ ๋ฏธ์ค ๊ธฐ๋ฐ์ ์๋น์ค ํ๊ฒฝ์์ ์ฝ๋ ์ค์ฌ์ผ๋ก ์ค๊ณ๋ฅผ ์งํํ๋ฉด ๊ด๋ฆฌ ํฌ์ธํธ๊ฐ ๋ง์์ง ๋ฟ๋ง ์๋๋ผ, ๋ณ๋ ฌ ์ฒ๋ฆฌ, ํธ๋์ญ์ ๊ด๋ฆฌ, ์์ธ ์ฒ๋ฆฌ ๋ฑ ๊ณ ๋ คํด์ผ ํ ์ฌํญ์ด ๋ง์์ง๋๋ค. ์ด๋ฌํ ๋ณต์ก์ฑ์ผ๋ก ์ธํด ์๋์ ์ผ๋ก ๋ ๋ง์ ์ธ๋ ฅ๊ณผ ๋ฆฌ์์ค๊ฐ ํ์ํ๊ฒ ๋ฉ๋๋ค.
๋ง๋ฌด๋ฆฌ
๋ด๋ฅ์ค์ ๊ฒ์ ํ์ดํ๋ผ์ธ์ ํจ์จ์ ์ด๊ณ ํธ๋ฆฌํ ๊ด๋ฆฌ๋ฅผ ํตํด ์ด์ ๋ฆฌ์์ค๋ฅผ ์ต์ํํ๋ ๋ฐ ์ด์ ์ ๋ง์ถฐ ์ค๊ณ๋์์ต๋๋ค. ๋ง์ฝ AWS ๊ด๋ฆฌํ ์๋น์ค๋ฅผ ์ฌ์ฉํ์ง ์์๋ค๋ฉด, ๊ฐ ํ๋ก์ธ์ค๋ง๋ค ๋ณ๋์ ๊ตฌ์ถ ๋ฐ ์ด์ ์ธ๋ ฅ์ด ํ์ํ์ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค. ์๋ฅผ ๋ค์ด cron ๋ฐฐ์น ์์คํ , ๋น ๋ฅด๊ณ ์์ ์ ์ธ ๋ฐ์ดํฐ ์ถ์ถ ์์คํ , ๊ฒ์์์ง ํด๋ฌ์คํฐ๋ง, ๋ชจ๋ํฐ๋ง ๋ฑ ๋ค์ํ ์์๋ฅผ ์ง์ ๊ด๋ฆฌํด์ผ ํ์ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ AWS ์๋น์ค๋ฅผ ํ์ฉํ ETL ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํจ์ผ๋ก์จ, ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ ์ฐํ๊ฒ ์กฐ์ ํ ์ ์์๊ณ ๋ชจ๋ ๋จ๊ณ๋ฅผ ์๋ํํด ๊ด๋ฆฌ ๋ถ๋ด์ ํฌ๊ฒ ์ค์ผ ์ ์์์ต๋๋ค. ๋ํ, ๋น์ฆ๋์ค์ ์๊ตฌ์ฌํญ์ด ๋ณ๋๋ ๋์๋ ์ ์ํ๊ฒ ๋์ํ ์ ์๋ค๋ ์ ์ด ํฐ ์ฅ์ ์ด์์ต๋๋ค. ์คํฌ๋ฆฝํธ๋ฅผ ๋ฐ๋ก ์์ ํ๊ณ ํ ์คํธํ ์ ์์ด, ๋ณ๋์ ๋น๋ ๊ณผ์ ์์ด๋ ๋น ๋ฅด๊ฒ ์กฐ์ ์ด ๊ฐ๋ฅํ๋ค๋ ์ ์ด ๋งค์ฐ ํธ๋ฆฌํ์ต๋๋ค.
์๋ํ์ ํธ๋ฆฌ์ฑ ๋ฟ๋ง ์๋๋ผ ๊ฐ ๋จ๊ณ์ ์ญํ ์ ๋ช ํํ ๋ถ๋ฆฌํ์ฌ ์ ์ง ๋ณด์์ ํจ์จ์ ๋์ผ ์ ์์๊ณ AWS ํ๊ฒฝ์์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ์ฌ ์๋๋ฅผ ๋ณด์ฅํ ์ ์์์ต๋๋ค. ์ด์ฒ๋ผ AWS ์๋น์ค๋ฅผ ํ์ฉํ๋ฉด ์ ์ ๋ฆฌ์์ค๋ก๋ ์ถฉ๋ถํ ์๋ํ์ ์ ์ฐ์ฑ์ ๊ธฐ๋ฐ์ผ๋ก ํ ๊ฒ์ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ์ฌ ์์ ์ ์ผ๋ก ์ด์ํ ์ ์์ต๋๋ค.

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
