-
๋ฉฑ๋ฑ์ฑ(Idempotence)์ ์ปดํจํฐ ๊ณผํ์์ ์์ฃผ ๋ฑ์ฅํ๋ ์ค์ํ ๊ฐ๋ ์ ๋๋ค. ์๋์ ์ผ๋ฐ์ ์ธ ์๋ฏธ์ API ๊ฐ๋ฐ๊ณผ์ ๊ด๋ จ์ฑ์ ๋๋์ด ์์ธํ ์ค๋ช ๋๋ฆฌ๊ฒ ์ต๋๋ค.
๐ก ๋ฉฑ๋ฑ์ฑ(Idempotence)์ด๋?
๋ฉฑ๋ฑ์ฑ์ด๋ ๋์ผํ ์ฐ์ฐ์ ์ฌ๋ฌ ๋ฒ ์ํํด๋ ๊ฒฐ๊ณผ๊ฐ ๊ฐ์์ง๋ ์ฑ์ง์ ๋งํฉ๋๋ค. ์ํ์์ ์ถ๋ฐํ ๊ฐ๋ ์ธ๋ฐ, ์๋ฅผ ๋ค์ด ํจ์
f(x)๊ฐ ์์ ๋ ๋ค์์ด ์ฑ๋ฆฝํ๋ฉด ๋ฉฑ๋ฑํจ์๋ผ๊ณ ํฉ๋๋ค:f(f(x)) = f(x)์์ (์ํ์ ๊ด์ )
- ์ ๋๊ฐ ํจ์:
| |x|| = |x| - ์งํฉ์ ํฉ์งํฉ ์ฐ์ฐ:
A โช A = A
๐ ๋ฉฑ๋ฑ์ฑ๊ณผ API ๊ฐ๋ฐ
์น API ์ค๊ณ ์, ๋ฉฑ๋ฑ์ฑ์ ์์ ์ ์ด๊ณ ์์ธก ๊ฐ๋ฅํ API๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๋งค์ฐ ์ค์ํ ์ฑ์ง์ ๋๋ค. ํนํ REST API์์๋ ๊ฐ HTTP ๋ฉ์๋๊ฐ ๋ฉฑ๋ฑ์ฑ์ ๊ฐ์ง์ง๋ฅผ ์ค๊ณ ์ ๋ช ํํ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
CreatedMon, 26 May 2025 20:20:45 +0900 - ์ ๋๊ฐ ํจ์:
-
Object[] ์ ArrayList ์ ์ฐจ์ด
์๋ฅผ ๋ค์ด Partner๋ผ๋ ํด๋์ค๊ฐ ์์ ๋
Partner[] p = new ArrayList์ ๊ฐ์ ์ฝ๋๋ ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด์ ๋ArrayList๋ Java์ ์ปฌ๋ ์ (List) ํ์ ์ด๊ณ ,Partner[]๋ ๋ฐฐ์ด ํ์ ์ด๊ธฐ ๋๋ฌธ์ ์๋ก ํธํ๋์ง ์๋ ํ์ ์ ๋๋ค.
๐ ์ ํํ ์ฐจ์ด์
Partner[]โ ๊ณ ์ ๋ ํฌ๊ธฐ์ ๋ฐฐ์ดArrayList<Partner>โ ๊ฐ๋ณ ํฌ๊ธฐ์ ๋ฆฌ์คํธ (๋ฐฐ์ด ๊ธฐ๋ฐ์ ์ปฌ๋ ์ )
โ ์ฌ๋ฐ๋ฅธ ์ฌ์ฉ๋ฒ
1.
ArrayList๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ ๋List<Partner> p = new ArrayList<>(); p.add(new Partner("name1")); p.add(new Partner("name2"));- ๋ฆฌ์คํธ๋ก ์ ์ธํ๊ณ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ง์ต๋๋ค.
- ์ด ๋ฐฉ๋ฒ์ด ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ ์ ์ฐํ๊ณ ํธ๋ฆฌํฉ๋๋ค.
2.
ArrayListโPartner[]๋ก ๋ณํ์ด ํ์ํ ๊ฒฝ์ฐList<Partner> pList = new ArrayList<>(); pList.add(new Partner("a")); pList.add(new Partner("b")); Partner[] pArray = pList.toArray(new Partner[0]); // ๋ฐฐ์ด๋ก ๋ณํ
โ ๏ธ ์๋ชป๋ ์์
Partner[] p = new ArrayList<>(); // โ ์ปดํ์ผ ์๋ฌ: incompatible types
โ ์์ฝ
๋ชฉ์ ์ฝ๋ ArrayList์ ์ธList<Partner> p = new ArrayList<>();๋ฆฌ์คํธ โ ๋ฐฐ์ด ๋ณํ Partner[] pArray = pList.toArray(new Partner[0]);๋ฐฐ์ด๋ณด๋ค
ArrayList๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ผ๋ก ๋ ์์ ํ๊ณ ์ ์ฐํฉ๋๋ค. ๋ค๋ง ๋ฐฐ์ด์ด ํ์ํ API์ ํธํํ๊ฑฐ๋ ์ฑ๋ฅ์ ์ด์ ์ด ํ์ํ ๊ฒฝ์ฐ ๋ฐฐ์ด ๋ณํ์ ์ฌ์ฉํ์ธ์.CreatedWed, 21 May 2025 19:20:45 +0900 -
Redis์์
Pub/Sub(Publish/Subscribe) ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋น๊ต์ ๊ฐ๋จํฉ๋๋ค. ์๋๋ ๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ ๋ฐฉ๋ฒ๊ณผ ์์ ์ ๋๋ค.
๐ง ๊ฐ๋ ์์ฝ
Redis Pub/Sub๋ ๋ฉ์์ง ๋ธ๋ก์ปค ์ญํ ์ ์ํํ์ฌ, ํ ํด๋ผ์ด์ธํธ๊ฐ ๋ฉ์์ง๋ฅผ ๋ฐํ(Publish)ํ๋ฉด, ํด๋น ์ฑ๋์ ๊ตฌ๋ (Subscribe)ํ๊ณ ์๋ ๋ค๋ฅธ ํด๋ผ์ด์ธํธ๋ค์ด ์ค์๊ฐ์ผ๋ก ๊ทธ ๋ฉ์์ง๋ฅผ ๋ฐ๊ฒ ๋ฉ๋๋ค.
- Publisher: ์ฑ๋์ ๋ฉ์์ง๋ฅผ ๋ฐํํ๋ ํด๋ผ์ด์ธํธ
- Subscriber: ํน์ ์ฑ๋์ ๊ตฌ๋ ํ๊ณ ๋ฉ์์ง๋ฅผ ๋ฐ๋ ํด๋ผ์ด์ธํธ
๐ ๋ช ๋ น์ด
PUBLISH <channel> <message>: ๋ฉ์์ง๋ฅผ ๋ฐํSUBSCRIBE <channel> [<channel> ...]: ์ฑ๋ ๊ตฌ๋UNSUBSCRIBE [<channel> ...]: ์ฑ๋ ๊ตฌ๋ ์ทจ์
๐ป ์์ (CLI ๊ธฐ์ค)
ํฐ๋ฏธ๋ 1 โ Subscriber
redis-cli > SUBSCRIBE newsํฐ๋ฏธ๋ 2 โ Publisher
redis-cli > PUBLISH news "Hello from Redis!"Subscriber๋ ๋ค์๊ณผ ๊ฐ์ ์๋ต์ ๋ฐ์ต๋๋ค:
CreatedWed, 21 May 2025 14:20:45 +0900 -
Grafana Dashboard ์ค์
{ "annotations": { "list": [ { "builtIn": 1, "datasource": { "type": "grafana", "uid": "-- Grafana --" }, "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "editable": false, "fiscalYearStartMonth": 0, "graphTooltip": 0, "links": [], "liveNow": false, "panels": [ { "datasource": { "type": "prometheus", "uid": "d594a822-806b-41e9-8c74-135eb41505a2" }, "gridPos": { "h": 3, "w": 24, "x": 0, "y": 0 }, "id": 1, "targets": [ { "datasource": { "type": "prometheus", "uid": "d594a822-806b-41e9-8c74-135eb41505a2" }, "refId": "A" } ], "type": "welcome" }, { "datasource": { "type": "prometheus", "uid": "d594a822-806b-41e9-8c74-135eb41505a2" }, "gridPos": { "h": 9, "w": 24, "x": 0, "y": 3 }, "id": 123123, "targets": [ { "datasource": { "type": "prometheus", "uid": "d594a822-806b-41e9-8c74-135eb41505a2" }, "refId": "A" } ], "type": "gettingstarted" }, { "datasource": { "type": "prometheus", "uid": "d594a822-806b-41e9-8c74-135eb41505a2" }, "gridPos": { "h": 15, "w": 12, "x": 0, "y": 12 }, "id": 3, "links": [], "options": { "folderUID": "", "includeVars": false, "keepTime": false, "maxItems": 30, "query": "", "showHeadings": true, "showRecentlyViewed": true, "showSearch": false, "showStarred": true, "tags": [] }, "pluginVersion": "10.3.3", "targets": [ { "datasource": { "type": "prometheus", "uid": "d594a822-806b-41e9-8c74-135eb41505a2" }, "refId": "A" } ], "title": "Dashboards", "type": "dashlist" }, { "datasource": { "type": "prometheus", "uid": "d594a822-806b-41e9-8c74-135eb41505a2" }, "gridPos": { "h": 15, "w": 12, "x": 12, "y": 12 }, "id": 4, "links": [], "options": { "feedUrl": "https://grafana.com/blog/news.xml", "showImage": true }, "targets": [ { "datasource": { "type": "prometheus", "uid": "d594a822-806b-41e9-8c74-135eb41505a2" }, "refId": "A" } ], "title": "Latest from the blog", "type": "news" } ], "refresh": "", "schemaVersion": 39, "tags": [], "templating": { "list": [] }, "time": { "from": "now-6h", "to": "now" }, "timepicker": { "hidden": true, "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ], "type": "timepicker" }, "timezone": "browser", "title": "Home", "version": 0, "weekStart": "" }์ด JSON์ Grafana ๋์๋ณด๋ ์ค์ ํ์ผ์ ๋๋ค. ๊ตฌ์ฒด์ ์ผ๋ก๋ Grafana์์ “Home"์ด๋ผ๋ ์ด๋ฆ์ ๊ธฐ๋ณธ ๋์๋ณด๋๋ฅผ ์ ์ํ ๊ตฌ์ฑ์ ๋๋ค. ์๋์ ์ฃผ์ ํญ๋ชฉ๋ค์ ์ค๋ช ๋๋ฆฌ๊ฒ ์ต๋๋ค.
CreatedTue, 20 May 2025 20:20:45 +0900 -
๋์์ ์คํธ๋ฆฌ๋ฐ์ ์ฌ์ฉ๋๋ ์ฃผ์ ๊ธฐ์ ๋ฐ ํด์ ๋ค์ํ ๋ชฉ์ (์: ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ, VOD, ์ฝํ ์ธ ์ ์ก, ์ธ์ฝ๋ฉ, ํ๋ ์ด์ด ๊ตฌํ ๋ฑ)์ ๋ฐ๋ผ ๊ตฌ๋ถ๋ฉ๋๋ค. ์๋์ ์ฃผ์ ๊ธฐ์ ๊ณผ ํด์ ์์ญ๋ณ๋ก ์ ๋ฆฌํด๋๋ฆด๊ฒ์.
1. ๋น๋์ค ์ธ์ฝ๋ฉ ๋ฐ ํธ๋์ค์ฝ๋ฉ
- FFmpeg: ์คํ์์ค ๋ฉํฐ๋ฏธ๋์ด ์ฒ๋ฆฌ ๋๊ตฌ. ์ธ์ฝ๋ฉ, ๋์ฝ๋ฉ, ํธ๋์ค์ฝ๋ฉ, ํฌ๋งท ๋ณ๊ฒฝ, ํํฐ๋ง ๋ฑ์ ์ฌ์ฉ.
- x264 / x265: ๊ฐ๊ฐ H.264, H.265 ํ์ค ์ธ์ฝ๋ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ.
- AWS Elemental MediaConvert: AWS์์ ์ ๊ณตํ๋ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ ํธ๋์ค์ฝ๋ฉ ์๋น์ค.
2. ์คํธ๋ฆฌ๋ฐ ํ๋กํ ์ฝ
- HLS (HTTP Live Streaming): ์ ํ์ด ๊ฐ๋ฐ. ๋๋ถ๋ถ์ ํ๋ซํผ์์ ์ง์๋๋ฉฐ, ์ธ๊ทธ๋จผํธ ๋ฐฉ์.
- DASH (Dynamic Adaptive Streaming over HTTP): MPEG ํ์ค ๊ธฐ๋ฐ์ผ๋ก, HLS์ ๋น์ทํ์ง๋ง ํ๋ซํผ ๋ ๋ฆฝ์ .
- RTMP (Real-Time Messaging Protocol): ์ฃผ๋ก ๋ผ์ด๋ธ ๋ฐฉ์ก์ ์ฌ์ฉ๋๋ฉฐ, YouTube Live, Twitch ๋ฑ์์ ์ฌ์ ํ ํ์ฉ.
- WebRTC: ์ง์ฐ์ด ๊ทนํ ๋ฎ์ ์ค์๊ฐ ์๋ฐฉํฅ ํต์ ์ ์ต์ ํ๋ ์คํธ๋ฆฌ๋ฐ ํ๋กํ ์ฝ.
3. ์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ (CDN)
- Cloudflare Stream / CDN: ๋น ๋ฅด๊ณ ์์ ์ ์ธ ์ฝํ ์ธ ์ ์ก์ ์ํ ๊ธ๋ก๋ฒ ๋คํธ์ํฌ.
- AWS CloudFront, Akamai, Fastly: ๋ํ ์คํธ๋ฆฌ๋ฐ ์๋น์ค์์ ๋ง์ด ์ฌ์ฉ.
4. ํ๋ ์ด์ด ๋ฐ ํ๋ก ํธ์๋ ๋๊ตฌ
- Video.js: HTML5 ๊ธฐ๋ฐ์ ์คํ์์ค ๋น๋์ค ํ๋ ์ด์ด.
- Shaka Player: ๊ตฌ๊ธ์ด ๋ง๋ MPEG-DASH ๋ฐ HLS ์ง์ ์คํ์์ค ํ๋ ์ด์ด.
- HLS.js: JavaScript ๊ธฐ๋ฐ HLS ์ฌ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ.
- ExoPlayer (Android), AVPlayer (iOS): ๋ชจ๋ฐ์ผ ์ฑ์ฉ ๊ธฐ๋ณธ ํ๋ ์ด์ด SDK.
5. ๋ผ์ด๋ธ ์คํธ๋ฆฌ๋ฐ ํ๋ซํผ/์๋น์ค
- OBS Studio (Open Broadcaster Software): ๋ฌด๋ฃ ๋ผ์ด๋ธ ๋ฐฉ์ก ๋๊ตฌ, Twitch, YouTube์ ๋ฐฉ์ก ๊ฐ๋ฅ.
- StreamYard, Restream, Wirecast: ๋ผ์ด๋ธ ๋ฉํฐํ๋ซํผ ์คํธ๋ฆฌ๋ฐ ํด.
- Wowza Streaming Engine: ์ํฐํ๋ผ์ด์ฆ๊ธ ๋ผ์ด๋ธ ๋ฐ VOD ์คํธ๋ฆฌ๋ฐ ์๋ฒ.
6. DRM (๋์งํธ ์ ์๊ถ ๊ด๋ฆฌ) ๋ฐ ๋ณด์
- Widevine (Google), PlayReady (Microsoft), FairPlay (Apple): ๊ฐ ํ๋ซํผ์ฉ DRM ์์คํ .
- AES-128 Encryption: HLS์ ํจ๊ป ์ฌ์ฉ๋๋ ์ฝํ ์ธ ์ํธํ ํ์ค.
7. ๋ชจ๋ํฐ๋ง ๋ฐ ๋ถ์
- Mux, Conviva, Bitmovin Analytics: ์ฌ์ฉ์ ๊ฒฝํ, ๋ฒํผ๋ง, ์์ฒญ ํ๋ ๋ถ์ ๋ฑ ์ ๊ณต.
- Prometheus + Grafana: ์๋ฒ ์ธก ์คํธ๋ฆฌ๋ฐ ์ฑ๋ฅ ๋ฐ ์งํ ๋ชจ๋ํฐ๋ง.
CreatedSun, 18 May 2025 20:20:45 +0900 -
MySQL์์ Slow Query(์ฌ๋ก์ฐ ์ฟผ๋ฆฌ) ๋ฅผ ๋ชจ๋ํฐ๋งํ๋ ๊ฒ์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ ์ค์ํ ์์ ์ ๋๋ค. ๋ค์์ ์ฌ๋ก์ฐ ์ฟผ๋ฆฌ๋ฅผ ๋ชจ๋ํฐ๋งํ๋ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ๋ค์ ๋๋ค:
1. ์ฌ๋ก์ฐ ์ฟผ๋ฆฌ ๋ก๊ทธ ํ์ฑํํ๊ธฐ
์ฌ๋ก์ฐ ์ฟผ๋ฆฌ๋ฅผ ๊ธฐ๋กํ๊ธฐ ์ํด MySQL ์ค์ ์ ์กฐ์ ํฉ๋๋ค.
๋ฐฉ๋ฒ 1:
my.cnf๋๋my.iniํ์ผ ์์ [mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 1 log_queries_not_using_indexes = 1slow_query_log: ์ฌ๋ก์ฐ ์ฟผ๋ฆฌ ๋ก๊ทธ ๊ธฐ๋ฅ ํ์ฑํslow_query_log_file: ๋ก๊ทธ ํ์ผ ์์นlong_query_time: ๋ช ์ด ์ด์ ๊ฑธ๋ฆฌ๋ ์ฟผ๋ฆฌ๋ฅผ ๋๋ฆฐ ์ฟผ๋ฆฌ๋ก ๊ฐ์ฃผํ ์ง ์ค์ (์ด ๋จ์)log_queries_not_using_indexes: ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ง ์๋ ์ฟผ๋ฆฌ๋ ๋ก๊ทธ์ ๊ธฐ๋ก
์ค์ ํ MySQL์ ์ฌ์์ํด์ผ ๋ฐ์๋ฉ๋๋ค.
CreatedTue, 13 May 2025 20:20:45 +0900