[AWS] Cloudfront: KeyValueStore
Cloudfront KeyValueStore๋ Cloudfront Function์ ๋ณด์กฐํ๋ ๋ถ๊ฐ๊ธฐ๋ฅ์ด๋ค.
Function์์ ๋ญ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์์ ์ผ๋ก ์ ์ฅํ๊ณ ๊บผ๋ด์ธ ํ์๊ฐ ์์๋ ์ฌ์ฉํ๋ค.
ํน์ํ๋๊ฑฐ๋ผ public access ๊ฐ๋ฅํ ๋ฒ์ฉ DB๋ ์๋๊ณ , CloudFront Function ์ฃ์ง์์๋ง ์ ๊ทผ ๊ฐ๋ฅํ๋ค.
๋ค๋ฅธ ๋ฐ์ดํฐ ์คํ ๋ฆฌ์ง๋ค๊ณผ ์ฐจ๋ณ๋๋ ์ฅ์ ์ ๋๋ถ๋ถ ๋ฆฌ์ ์ ๋ชจ๋ ์ฃ์ง ์์น์ ๋ฐ์ดํฐ๊ฐ ๋ถํฌ๋์ด์ ์ต์ํ์ ๋ ์ดํด์๋ก ๋น ๋ฅด๊ฒ ๋์ํ๋ค๋ ๊ฒ์ด๋ค.
๋ํ์ ์ธ ์ฌ์ฉ๋ก๋ A/B ํ
์คํธ ๋ผ์ฐํ
์ ํ ๋ ๋ถํฌ ๋น์จ ๋ฑ์ ์กฐ์ ํ๋ค๊ฑฐ๋ ํ๋ ๊ฒ์ด๋ค.
๋ฑํ ์ ํํ๋ ์ฌ์ฉ๋ฐฉ๋ฒ์ด ์์ง๋ ์์ผ๋, ํธํ ๋๋ก ์ฐ๋ฉด ๋๋ค.
๊ด๋ จ ํฌ์คํธ
https://blog.naver.com/sssang97/223368455944
๋น์ฉ
https://aws.amazon.com/ko/cloudfront/pricing/
์ฝ๊ธฐ ๋น์ฉ์ด ์ ๋ ดํ๊ณ ์ฐ๊ธฐ ๋น์ฉ์ด ์กฐ๊ธ ๋น์ผ ํธ์ด๋ค.
์ฝ๊ธฐ๋ 100๋ง๊ฑด๋น 0.03๋ฌ๋ฌ๋ก ๊ฝค ์ธ๊ณ , ์ฐ๊ธฐ ๋ฑ์ 1000๊ฐ๋น 1๋ฌ๋ฌ๋ค.
๊ทผ๋ฐ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉ ํจํด ์์ฒด๊ฐ ์์ ์ด ๋น๋ฒํ ๊ฒ์ ์๋๋ ๋ณ ๋ฌธ์ ๊ฐ ๋ ๋ถ๋ถ์ ์๋๋ค. ์ด์ํ๊ฒ ์ฐ์ง๋ง ์์ผ๋ฉด.
KeyValueStore ๋ง๋ค๊ธฐ
์ผ๋จ ์คํ ์ด๋ถํฐ ํ๋ ๋ง๋ค์ด๋ณด์.

๊ทธ๋ฅ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋์ถฉ ๋ง๋ค์ด๋ ๋๋ค. ์ด๋ฆ๋ง ์ ์ง์.

๊ทธ๋ผ ์ฝ๊ฐ์ ๋๋ ์ด์ ํจ๊ป ๋ง๋ค์ด์ง๋๋ฐ, ์ด๊ฒ ์์ฒด๊ฐ ์ผ์ข
์ ํ
์ด๋ธ์ ์ญํ ์ ํ๋ค.

์ธ์ ๋ ๊ฐ์ ์ค์๊ฐ์ผ๋ก ์ถ๊ฐํ๊ฑฐ๋ ์์ ํ ์ ์๋ค.
A/B ๋ผ์ฐํ ๊ตฌ์ฑํด๋ณด๊ธฐ
KeyValue ์คํ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก A/B ๋ผ์ฐํ ํ๋ฅ ๊ฐ์ค์น๋ฅผ ์กฐ์ ํ๋ ๊ตฌ์ฑ์ ์ง๋ณด๋๋ก ํ๊ฒ ๋ค.

๋๋ /abtest๋ผ๋ ๊ฒฝ๋ก๋ก ์ ์์ ์๋ํ ๋, ๊ฐ์ค์น์ ๋ฐ๋ผ /abtest/a.html, /abtest/b.html ๋ฆฌ์์ค์ ๋ผ์ฐํ ์ ์ํค๋ ค๊ณ ํ๋ค. (URI ๋ฆฌ๋๋ ์ ์์ด)
๋จผ์ s3์ ํ์ผ์ ์ ์ ํ ์ ๋ก๋ํ๋ค.
๋ณ๊ฑด์๋ค.
๊ทธ๋ฆฌ๊ณ Cloudfront ํจ์๋ฅผ ๋ง๋ ํ์


KeyValueStore๋ฅผ ์ฐ๊ด์์ผ์ค๋ค.
๊ทธ๋ผ ์ ํจ์์์ ์ฌ์ฉํ ์ ์๋ ๊ณ ์ ID๊ฐ ์์ฑ๋๋ค.
ํจ์ ์ฌ์ฉ๋ฒ์ ๋ํด์๋ ๋ณ๋ ํฌ์คํธ๋ฅผ ์ฐธ๊ณ ํ๋ค.
https://blog.naver.com/sssang97/223368455944
์ฐ์ Store์ ์ด๊ธฐ๊ฐ์ ์ค์ ํด์ฃผ๊ณ
Function์ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
import cf from "cloudfront";
const kvsId = "...b00ac861e1d1";
const kvsHandle = cf.kvs(kvsId);
async function handler(event) {
const request = event.request;
if (request.uri == "/abtest") {
try {
let aWeight = await kvsHandle.get("a_weight");
let bWeight = await kvsHandle.get("b_weight");
aWeight = aWeight ? parseInt(aWeight) : 0;
bWeight = bWeight ? parseInt(bWeight) : 0;
const percentOfA = aWeight / (aWeight + bWeight);
const newUri = Math.random() < percentOfA ? "/abtest/a.html" : "/abtest/b.html";
request.uri = newUri;
return request;
} catch (err) {
console.log(`${request.uri} | ${err}`);
return request;
}
} else {
return request;
}
}
๊ฐ์ค์น์ ๋ฐ๋ผ ํ๋ฅ ๋ก ๋งค์นญ์์ผ์ฃผ๋ ๊ฐ๋จํ ์ฝ๋๋ค.
/abtest ๊ฒฝ๋ก๋ก ๋ค์ด์ฌ๋๋ง ํน๋ณ ์ฒ๋ฆฌ๋ฅผ ํด์คฌ๋ค.
ํจ์ ์ฝ๋๋ฅผ ๋ฐฐํฌํ๊ณ ,
Cloudfront ๋์์ ๋ทฐ์ด ์์ฒญ์ ํธ๋ฆฌ๊ฑฐํ๋ค.

๊ทธ๋ฆฌ๊ณ /abtest๋ก ์ ์ํด๋ณด๋ฉด


๋์ ํ๋ฅ ๋ก A๋ก๋ง ๋ผ์ฐํ
๋๊ณ , ๋ฎ์ ํ๋ฅ ๋ก B๊ฐ ๋ผ์ฐํ
๋ ๊ฒ์ด๋ค.
๋ฐ๋๋ก ๊ฐ์ค์น๋ฅผ ๋ฐ๊ฟ๋ณด๋ฉด
์ ํ์๋ ๋ช์ด ์ ๋๊ฐ ๊ฑธ๋ฆฐ๋ค.
๊ทธ๋ฌ๋ฉด ์ด์ ๋ฐ๋๋ก


B๊ฐ ๋น๋ฒํ๊ฒ ๋ผ์ฐํ
๋๋ค.
์ด๋ฐ ๋๋์ผ๋ก ์ฌ์ฉํ๋ฉด ๋๋ค.
์ฐธ์กฐ
https://aws.amazon.com/ko/blogs/korea/introducing-amazon-cloudfront-keyvaluestore-a-low-latency-datastore-for-cloudfront-functions/
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/kvs-with-functions.html