OpenAI ಕಡಿಮೆ-ಲೇಟೆನ್ಸಿಯ ವಾಯ್ಸ್ AI ಅನ್ನು ದೊಡ್ಡ ಪ್ರಮಾಣದಲ್ಲಿ ಹೇಗೆ ಒದಗಿಸುತ್ತದೆ
ಯಿ ಝಾಂಗ್ ಮತ್ತು ವಿಲಿಯಂ ಮೆಕ್ಡೊನಾಲ್ಡ್, ತಾಂತ್ರಿಕ ಸಿಬ್ಬಂದಿ ಸದಸ್ಯರಿಂದ
ವಾಯ್ಸ್ AI ನೈಸರ್ಗಿಕವಾಗಿ ಅನ್ನಿಸಬೇಕಾದರೆ ಸಂಭಾಷಣೆ ಮಾತಿನ ವೇಗದಲ್ಲೇ ಸಾಗಬೇಕು. ನೆಟ್ವರ್ಕ್ ಅಡ್ಡಿಯಾದಾಗ, ಜನರು ಅದನ್ನು ತಕ್ಷಣವೇ ಅಸಹಜ ವಿರಾಮಗಳು, ಮಧ್ಯೆ ಕಡಿದ ವ್ಯತ್ಯಯಗಳು, ಅಥವಾ ತಡವಾದ barge-in ರೂಪದಲ್ಲಿ ಕೇಳುತ್ತಾರೆ. ಇದು ChatGPT ವಾಯ್ಸ್ಗೆ, Realtime API ಬಳಸಿ ನಿರ್ಮಿಸುವ ಡೆವಲಪರ್ಗಳಿಗೆ, ಸಂವಹನಾತ್ಮಕ ವರ್ಕ್ಫ್ಲೋಗಳಲ್ಲಿ ಕೆಲಸ ಮಾಡುವ ಏಜೆಂಟ್ಗಳಿಗೆ, ಮತ್ತು ಬಳಕೆದಾರ ಇನ್ನೂ ಮಾತನಾಡುತ್ತಿರಲೇ ಆಡಿಯೊವನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಬೇಕಾದ ಮಾಡೆಲ್ಗಳಿಗೆ ಮಹತ್ವದ್ದಾಗಿದೆ.
OpenAI ಯ ಪ್ರಮಾಣದಲ್ಲಿ, ಇದು ಮೂರು ಸ್ಪಷ್ಟ ಅವಶ್ಯಕತೆಗಳಾಗಿ ಅನುವಾದಗೊಳ್ಳುತ್ತದೆ.
- ವಾರಕ್ಕೆ 900 ಮಿಲಿಯನ್ಗಿಂತ ಹೆಚ್ಚು ಸಕ್ರಿಯ ಬಳಕೆದಾರರಿಗೆ ಜಾಗತಿಕ ವ್ಯಾಪ್ತಿ
- ಅಧಿವೇಶನ ಆರಂಭವಾದ ತಕ್ಷಣ ಬಳಕೆದಾರರು ಮಾತನಾಡಲು ಶುರುಮಾಡುವಂತೆ ವೇಗವಾದ ಸಂಪರ್ಕ ಸ್ಥಾಪನೆ
- ಕಡಿಮೆ ಮತ್ತು ಸ್ಥಿರ ಮೀಡಿಯಾ ರೌಂಡ್-ಟ್ರಿಪ್ ಸಮಯ, ಕಡಿಮೆ jitter ಮತ್ತು packet loss ಜೊತೆಗೆ, ಹೀಗಾಗಿ ಮಾತಿನ ತುರ್ನ್-ಟೇಕಿಂಗ್ ಚುರುಕಾಗಿ ಅನುಭವವಾಗುವುದು
ರಿಯಲ್-ಟೈಮ್ AI ಸಂವಹನಗಳಿಗೆ ಜವಾಬ್ದಾರಿಯಿರುವ OpenAI ತಂಡವು ಇತ್ತೀಚೆಗೆ ನಮ್ಮ WebRTC ಸ್ಟ್ಯಾಕ್ ಅನ್ನು ಮರುರಚಿಸಿತು, ಏಕೆಂದರೆ ಪ್ರಮಾಣ ಹೆಚ್ಚಾದಂತೆ ಪರಸ್ಪರ ಘರ್ಷಣೆಗೆ ಬಂದ ಮೂರು ನಿರ್ಬಂಧಗಳನ್ನು ಎದುರಿಸಬೇಕಾಯಿತು: ಪ್ರತಿ ಅಧಿವೇಶನಕ್ಕೆ ಒಂದು ಪೋರ್ಟ್ ಮೀಡಿಯಾ ಟರ್ಮಿನೇಶನ್ OpenAI ಮೂಲಸೌಕರ್ಯಕ್ಕೆ ಸರಿಯಾಗಿ ಹೊಂದುವುದಿಲ್ಲ, stateful ICE (Interactive Connectivity Establishment) ಮತ್ತು DTLS (Datagram Transport Layer Security) ಅಧಿವೇಶನಗಳಿಗೆ ಸ್ಥಿರ ಮಾಲಿಕತ್ವ ಬೇಕಾಗುತ್ತದೆ, ಮತ್ತು ಜಾಗತಿಕ ರೌಟಿಂಗ್ ಮೊದಲ-hop ಲೇಟೆನ್ಸಿಯನ್ನು ಕಡಿಮೆಯಾಗಿ ಇಡಬೇಕು. ಈ ಲೇಖನದಲ್ಲಿ, OpenAI ಮೂಲಸೌಕರ್ಯದ ಒಳಗೆ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಹೇಗೆ ರೌಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸುತ್ತಾ ಕ್ಲೈಂಟ್ಗಳಿಗೆ ಮಾನಕ WebRTC ವರ್ತನೆಯನ್ನು ಉಳಿಸಿಕೊಳ್ಳಲು ನಾವು ನಿರ್ಮಿಸಿದ ವಿಭಜಿತ relay plus transceiver ಆರ್ಕಿಟೆಕ್ಚರ್ನ್ನು ವಿವರಿಸುತ್ತೇವೆ.
WebRTC ಎನ್ನುವುದು ಬ್ರೌಸರ್ಗಳು, ಮೊಬೈಲ್ ಆಪ್ಗಳು, ಮತ್ತು ಸರ್ವರ್ಗಳ ನಡುವೆ ಕಡಿಮೆ-ಲೇಟೆನ್ಸಿಯ ಆಡಿಯೊ, ವೀಡಿಯೊ, ಮತ್ತು ಡೇಟಾವನ್ನು ಕಳುಹಿಸಲು ಬಳಸುವ ಮುಕ್ತ ಮಾನದಂಡವಾಗಿದೆ. ಇದನ್ನು ಸಾಮಾನ್ಯವಾಗಿ peer-to-peer ಕರೆಗಳಿಗೆ ಸಂಬಂಧಿಸಿ ನೋಡಲಾಗುತ್ತದೆ, ಆದರೆ ಇದು ಕ್ಲೈಂಟ್-ಟು-ಸರ್ವರ್ ರಿಯಲ್-ಟೈಮ್ ಸಿಸ್ಟಮ್ಗಳಿಗೆ ಸಹ ಪ್ರಾಯೋಗಿಕ ನೆಲೆಯಾಗಿದೆ, ಏಕೆಂದರೆ ಸಂವಹನಾತ್ಮಕ ಮೀಡಿಯಾದ ಕಠಿಣ ಭಾಗಗಳನ್ನು ಇದು ಮಾನಕೀಕರಿಸುತ್ತದೆ: ಸಂಪರ್ಕ ಸ್ಥಾಪನೆ ಮತ್ತು NAT (Network Address Translation) traversal ಗಾಗಿ ICE, ಗುಪ್ತೀಕೃತ ಸಾರಿಗಾಗಿ DTLS ಮತ್ತು SRTP (Secure Real-time Transport Protocol), ಆಡಿಯೊ ಸಂಕುಚನ ಮತ್ತು ಡಿಕೋಡಿಂಗ್ಗಾಗಿ codec negotiation, ಗುಣಮಟ್ಟ ನಿಯಂತ್ರಣಕ್ಕಾಗಿ RTCP (Real-time Transport Control Protocol), ಮತ್ತು echo cancellation ಮತ್ತು jitter buffering ಮೊದಲಾದ ಕ್ಲೈಂಟ್-ಪಕ್ಷದ ವೈಶಿಷ್ಟ್ಯಗಳು.
ಈ ಮಾನಕೀಕರಣ AI ಉತ್ಪನ್ನಗಳಿಗೆ ಮುಖ್ಯವಾಗಿದೆ. WebRTC ಇಲ್ಲದೆ, NAT ಗಳಾಚೆ ಸಂಪರ್ಕವನ್ನು ಹೇಗೆ ಸ್ಥಾಪಿಸಬೇಕು, ಮೀಡಿಯಾವನ್ನು ಹೇಗೆ ಎನ್ಕ್ರಿಪ್ಟ್ ಮಾಡಬೇಕು, codecs (ಪ್ರಸರಣ ಮತ್ತು ಡೀಕಂಪ್ರೆಷನ್ಗೆ ಆಯ್ಕೆಯಾದ coder-decoders) ಅನ್ನು ಹೇಗೆ ಸಂಧಾನಿಸಬೇಕು ಮತ್ತು ಬದಲಾಗುತ್ತಿರುವ ನೆಟ್ವರ್ಕ್ ಪರಿಸ್ಥಿತಿಗಳಿಗೆ ಹೇಗೆ ಹೊಂದಿಸಬೇಕು ಎಂಬುದಕ್ಕೆ ಪ್ರತಿಯೊಂದು ಕ್ಲೈಂಟ್ಗೂ ಬೇರೆ ಉತ್ತರ ಬೇಕಾಗುತ್ತಿತ್ತು. WebRTC ಜೊತೆಗೆ, ಬ್ರೌಸರ್ಗಳು ಮತ್ತು ಮೊಬೈಲ್ ಪ್ಲಾಟ್ಫಾರ್ಮ್ಗಳಾದ್ಯಂತ ಈಗಾಗಲೇ ಜಾರಿಗೊಂಡಿರುವ ಒಂದು ಪ್ರೋಟೋಕಾಲ್ ಸ್ಟ್ಯಾಕ್ ಮೇಲೆ ನಾವು ನಿರ್ಮಿಸಬಹುದು; ಹೀಗಾಗಿ ರಿಯಲ್-ಟೈಮ್ ಮೀಡಿಯಾವನ್ನು ಮಾಡೆಲ್ಗಳಿಗೆ ಸಂಪರ್ಕಿಸುವ ಮೂಲಸೌಕರ್ಯದ ಮೇಲೆ ನಮ್ಮ ಕೆಲಸವನ್ನು ಕೇಂದ್ರೀಕರಿಸಬಹುದು.
ನಾವು WebRTC ಪರಿಸರ ವ್ಯವಸ್ಥೆಯ ಮೇಲೆಯೂ ನಿರ್ಮಿಸುತ್ತೇವೆ; ಇದರಲ್ಲಿ ಪರಿಪಕ್ವ open-source ಜಾರಿಗಳು ಮತ್ತು ಬ್ರೌಸರ್ಗಳು, ಮೊಬೈಲ್ ಆಪ್ಗಳು, ಮತ್ತು ಸರ್ವರ್ಗಳು ಪರಸ್ಪರ ಕಾರ್ಯನಿರ್ವಹಿಸಬಲ್ಲಂತೆ ಇಡುವ ಮಾನದಂಡದ ಕೆಲಸ ಒಳಗೊಂಡಿವೆ. Justin Uberti (WebRTC ಯ ಮೂಲ ವಾಸ್ತುಶಿಲ್ಪಿಗಳಲ್ಲಿ ಒಬ್ಬರು) ಮತ್ತು Sean DuBois (Pion ನ ಸೃಷ್ಟಿಕರ್ತ ಮತ್ತು ನಿರ್ವಾಹಕ) ಅವರ ಮೂಲಭೂತ ಕೆಲಸವು ನಮ್ಮಂತಹ ತಂಡಗಳಿಗೆ ಕೆಳಮಟ್ಟದ ಸಾರಿಗೆ, ಎನ್ಕ್ರಿಪ್ಷನ್, ಮತ್ತು congestion-control ವರ್ತನೆಯನ್ನು ಮರುಆವಿಷ್ಕರಿಸುವ ಬದಲು ಯುದ್ಧಪರೀಕ್ಷಿತ ಮೀಡಿಯಾ ಮೂಲಸೌಕರ್ಯದ ಮೇಲೆ ನಿರ್ಮಿಸಲು ಸಾಧ್ಯಮಾಡಿತು. Justin ಮತ್ತು Sean ಇಬ್ಬರೂ ಈಗ OpenAI ಯಲ್ಲೇ ನಮ್ಮ ಸಹೋದ್ಯೋಗಿಗಳಾಗಿರುವುದು ನಮ್ಮ ಭಾಗ್ಯ; WebRTC ಮತ್ತು ರಿಯಲ್-ಟೈಮ್ AI ಯನ್ನು ಇನ್ನಷ್ಟು ಸಮೀಪಕ್ಕೆ ತರಲು ಅವರು ಮಾರ್ಗದರ್ಶನ ಮಾಡುತ್ತಿದ್ದಾರೆ.
AI ಗಾಗಿ, ಅತ್ಯಂತ ಮುಖ್ಯ ಗುಣವೆಂದರೆ ಆಡಿಯೊವು ನಿರಂತರ ಸ್ಟ್ರೀಮ್ ಆಗಿ ತಲುಪುವುದು. ಮಾತನಾಡುವ ಏಜೆಂಟ್ ಬಳಕೆದಾರ ಇನ್ನೂ ಮಾತನಾಡುತ್ತಿದ್ದಾಗಲೇ ಲಿಪ್ಯಂತರಿಸಲು, ರೀಜನಿಂಗ್ ಮಾಡಲು, ಉಪಕರಣಗಳನ್ನು ಕರೆಹಾಕಲು, ಅಥವಾ ಮಾತು ಸೃಷ್ಟಿಸಲು ಪ್ರಾರಂಭಿಸಬಹುದು; ಸಂಪೂರ್ಣ ಅಪ್ಲೋಡ್ ಆಗುವವರೆಗೂ ಕಾಯಬೇಕಾಗಿಲ್ಲ. ಸಂಭಾಷಣಾತ್ಮಕವಾಗಿ ಅನುಭವಿಸುವ ವ್ಯವಸ್ಥೆ ಮತ್ತು push-to-talk ರೀತಿಯಲ್ಲಿ ಅನುಭವಿಸುವ ವ್ಯವಸ್ಥೆಯ ನಡುವಿನ ವ್ಯತ್ಯಾಸ ಇದೇ.
ನಾವು WebRTC ಆಯ್ಕೆ ಮಾಡಿದ ನಂತರ, ಮುಂದಿನ ಪ್ರಶ್ನೆ ಎಂದರೆ ಅದನ್ನು ಎಲ್ಲಿ ಟರ್ಮಿನೇಟ್ ಮಾಡಬೇಕು (ಉದಾಹರಣೆಗೆ, ಎಡ್ಜ್ನಲ್ಲಿ WebRTC ಸಂಪರ್ಕವನ್ನು ನಾವು ಸ್ವೀಕರಿಸಿ ಮಾಲಿಕತ್ವ ವಹಿಸುವ ಸ್ಥಳ) ಮತ್ತು ಆ ಅಧಿವೇಶನಗಳನ್ನು inference backend ಗೆ ಹೇಗೆ ಸಂಪರ್ಕಿಸಬೇಕು ಎಂಬುದು. ಟರ್ಮಿನೇಶನ್ ಮುಖ್ಯ, ಏಕೆಂದರೆ ಅದು ರಿಯಲ್-ಟೈಮ್ ಅಧಿವೇಶನ ಸ್ಥಿತಿ, ಮೀಡಿಯಾ ಸಾರಿಗೆ, ರೌಟಿಂಗ್, ಲೇಟೆನ್ಸಿ, ಮತ್ತು ವೈಫಲ್ಯ ಪ್ರತ್ಯೇಕಿಕರಣವನ್ನು ನಾವು ಹೇಗೆ ನಿರ್ವಹಿಸುತ್ತೇವೆ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸುತ್ತದೆ.
SFU, ಅಂದರೆ selective forwarding unit, ಪ್ರತಿಯೊಬ್ಬ ಭಾಗವಹಿಸುವವರಿಂದ ಒಂದೊಂದು WebRTC ಸ್ಟ್ರೀಮ್ ಸ್ವೀಕರಿಸಿ ಅದನ್ನು ಇತರರಿಗೆ ಆಯ್ಕೆಯಿಂದ ಫಾರ್ವರ್ಡ್ ಮಾಡುವ ಮೀಡಿಯಾ ಸರ್ವರ್ ಆಗಿದೆ. ಈ ಮಾದರಿಯಲ್ಲಿ, SFU ಪ್ರತಿ ಭಾಗವಹಿಸುವವರಿಗೂ ಪ್ರತ್ಯೇಕ WebRTC ಸಂಪರ್ಕವನ್ನು ಟರ್ಮಿನೇಟ್ ಮಾಡುತ್ತದೆ, ಮತ್ತು AI ಅಧಿವೇಶನದಲ್ಲಿ ಇನ್ನೊಬ್ಬ ಭಾಗವಹಿಸುವವನಾಗಿ ಸೇರುತ್ತದೆ. ಗುಂಪು ಕರೆಗಳು, ತರಗತಿಗಳು, ಅಥವಾ ಸಹಯೋಗಿ ಸಭೆಗಳಂತಹ ಮೂಲತಃ ಬಹುಪಕ್ಷೀಯ ಉತ್ಪನ್ನಗಳಿಗೆ ಇದು ಒಳ್ಳೆಯ ಹೊಂದಾಣಿಕೆಯಾಗಬಹುದು. ಇದು audio codecs, RTCP ಸಂದೇಶಗಳು, data channels, recording, ಮತ್ತು ಪ್ರತಿ ಸ್ಟ್ರೀಮ್ ನೀತಿಯನ್ನು ಒಂದೇ ಸ್ಥಳದಲ್ಲಿ ಇಡುತ್ತದೆ.1
ಕ್ಲೈಂಟ್-ಟು-AI ಉತ್ಪನ್ನಗಳಲ್ಲಿಯೂ ಸಹ, SFU ಬಹು ಬಾರಿ default ಆರಂಭಿಕ ಬಿಂದುವಾಗಿರುತ್ತದೆ, ಏಕೆಂದರೆ ಇದು signaling, media routing, recording, observability, ಮತ್ತು ಮಾನವ handoff ಅಥವಾ ಇನ್ನಷ್ಟು ಭಾಗವಹಿಸುವವರನ್ನು ಸೇರಿಸುವಂತಹ ಭವಿಷ್ಯದ ವಿಸ್ತರಣೆಗಳಿಗಾಗಿ ಈಗಾಗಲೇ ಸಾಬೀತಾದ ಒಂದೇ ಸಿಸ್ಟಮ್ ಅನ್ನು ತಂಡಗಳು ಮರುಬಳಕೆ ಮಾಡಲು ಅವಕಾಶ ನೀಡುತ್ತದೆ.
ಆದರೆ ನಮ್ಮ ವರ್ಕ್ಲೋಡ್ ವಿಭಿನ್ನವಾಗಿದೆ. ಹೆಚ್ಚಿನ ಅಧಿವೇಶನಗಳು 1:1 — ಒಬ್ಬ ಬಳಕೆದಾರ ಒಬ್ಬ ಮಾಡೆಲ್ ಜೊತೆ ಮಾತನಾಡುವುದು, ಅಥವಾ ಒಂದು ಆಪ್ಲಿಕೇಶನ್ ಒಂದು ರಿಯಲ್-ಟೈಮ್ ಏಜೆಂಟ್ ಜೊತೆ ಮಾತನಾಡುವುದು — ಮತ್ತು ಪ್ರತಿ ತುರ್ನ್ನಲ್ಲೂ ಲೇಟೆನ್ಸಿ ಸಂವೇದನಾಶೀಲತೆಯಿದೆ. ಈ ರೀತಿಯ ಟ್ರಾಫಿಕ್ಗಾಗಿ, ನಾವು transceiver ಮಾದರಿಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿಕೊಂಡೆವು: WebRTC edge service ಕ್ಲೈಂಟ್ ಸಂಪರ್ಕವನ್ನು ಟರ್ಮಿನೇಟ್ ಮಾಡುತ್ತದೆ, ನಂತರ ಮೀಡಿಯಾ ಮತ್ತು ಈವೆಂಟ್ಗಳನ್ನು ಮಾಡೆಲ್ inference, transcription, speech generation, tool use, ಮತ್ತು orchestration ಗಾಗಿ ಸರಳ ಆಂತರಿಕ ಪ್ರೋಟೋಕಾಲ್ಗಳಿಗೆ ಪರಿವರ್ತಿಸುತ್ತದೆ.
ಈ ವಿನ್ಯಾಸದಲ್ಲಿ, ICE connectivity checks, DTLS handshake, SRTP encryption keys, ಮತ್ತು session lifecycle ಸೇರಿದಂತೆ WebRTC session state ನ ಸಂಪೂರ್ಣ ಮಾಲಿಕತ್ವ transceiver ಗೆ ಮಾತ್ರ ಇರುತ್ತದೆ. ಇಲ್ಲಿ “termination” ಎಂದರೆ ಆ handshakes ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿ ಮೀಡಿಯಾವನ್ನು ಎನ್ಕ್ರಿಪ್ಟ್ ಅಥವಾ ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡುವ ಎಂಡ್ಪಾಯಿಂಟ್ transceiver ಎಂಬುದಾಗಿದೆ. ಆ ಸ್ಥಿತಿಯನ್ನು ಒಂದೇ ಸ್ಥಳದಲ್ಲಿ ಇಡುವುದರಿಂದ session ownership ಅನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ಸುಲಭವಾಯಿತು, ಮತ್ತು backend services ಗಳು ಸ್ವತಃ WebRTC peers ಆಗಿ ವರ್ತಿಸುವ ಬದಲು ಸಾಮಾನ್ಯ services ಗಳಂತೆ scale ಆಗಲು ಇದು ಅವಕಾಶ ನೀಡಿತು.
ನಾವು transceiver ಮಾದರಿಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿದ ನಂತರ, ನಮ್ಮ ಮೊದಲ ಜಾರಿ Pion ಮೇಲೆ ನಿರ್ಮಿಸಲಾದ ಒಂದು ಏಕೈಕ Go service ಆಗಿತ್ತು; ಅದು signaling ಹಾಗೂ media termination ಎರಡನ್ನೂ ನಿರ್ವಹಿಸುತ್ತಿತ್ತು. ಇದು ChatGPT ವಾಯ್ಸ್, Realtime API ಯ WebRTC ಎಂಡ್ಪಾಯಿಂಟ್, ಮತ್ತು ಹಲವು ಸಂಶೋಧನಾ ಯೋಜನೆಗಳನ್ನು ಚಾಲಿತಗೊಳಿಸುತ್ತದೆ.
ಕಾರ್ಯಾಚರಣಾತ್ಮಕವಾಗಿ, transceiver service ಎರಡು ಕೆಲಸಗಳನ್ನು ಮಾಡುತ್ತದೆ.
- ಸಿಗ್ನಲಿಂಗ್: SDP ಮಾತುಕತೆ, ಕೋಡೆಕ್ ಆಯ್ಕೆ, ICE ರುಜುವಾತುಗಳು ಮತ್ತು ಸೆಷನ್ ಸೆಟಪ್
- ಮೀಡಿಯಾ: ಡೌನ್ಸ್ಟ್ರೀಮ್ WebRTC ಸಂಪರ್ಕಗಳನ್ನು ಅಂತ್ಯಗೊಳಿಸುವುದು ಮತ್ತು ಇನ್ಫರೆನ್ಸ್ ಹಾಗೂ ಆರ್ಕೆಸ್ಟ್ರೇಶನ್ ಉದ್ದೇಶಗಳಿಗಾಗಿ ಬ್ಯಾಕೆಂಡ್ ಸೇವೆಗಳಿಗೆ ಅಪ್ಸ್ಟ್ರೀಮ್ ಸಂಪರ್ಕಗಳನ್ನು ಕಾಯ್ದುಕೊಳ್ಳುವುದು
ನಮ್ಮ ಉಳಿದ ಮೂಲಸೌಕರ್ಯಗಳಂತೆ ಈ ಸೇವೆಯೂ ಕೂಡ ಕುಬರ್ನೆಟಿಸ್ (Kubernetes) ಮೇಲೆ ನಡೆಯಬೇಕೆಂದು ನಾವು ಬಯಸಿದ್ದೆವು. ಇಲ್ಲಿ ಕೆಲಸದ ಹೊರೆಗೆ (workloads) ಅನುಗುಣವಾಗಿ ಸಾಮರ್ಥ್ಯವನ್ನು ಹೆಚ್ಚಿಸಬಹುದು ಅಥವಾ ಕಡಿಮೆ ಮಾಡಬಹುದು, ಮತ್ತು ಬೇಡಿಕೆಗೆ ತಕ್ಕಂತೆ ಹೋಸ್ಟ್ಗಳ ನಡುವೆ ವರ್ಗಾಯಿಸಬಹುದು. ಆದರೆ ಸಾಂಪ್ರದಾಯಿಕ 'ಒಂದು ಸೆಷನ್ಗೆ ಒಂದು ಪೋರ್ಟ್' (one-port-per-session) ಎನ್ನುವ WebRTC ಮಾದರಿಯು ಈ ಪರಿಸರಕ್ಕೆ ಅಷ್ಟಾಗಿ ಹೊಂದುವುದಿಲ್ಲ. ಏಕೆಂದರೆ ಇದು ದೊಡ್ಡ ಮಟ್ಟದ ಸಾರ್ವಜನಿಕ UDP ಪೋರ್ಟ್ ಶ್ರೇಣಿಗಳನ್ನು ಅವಲಂಬಿಸಿದೆ, ಇವುಗಳನ್ನು ಪಾಡ್ಗಳನ್ನು (pods) ಸೇರಿಸುವಾಗ, ತೆಗೆದುಹಾಕುವಾಗ ಅಥವಾ ಮರುಹಂಚಿಕೆ ಮಾಡುವಾಗ ಬಹಿರಂಗಪಡಿಸುವುದು, ಸುರಕ್ಷಿತವಾಗಿಡುವುದು ಮತ್ತು ಸಂರಕ್ಷಿಸುವುದು ಕಷ್ಟಕರವಾಗಿರುತ್ತದೆ.2
ಮೊದಲ ಸಮಸ್ಯೆಯೆಂದರೆ 'ಒಂದು ಸೆಷನ್ಗೆ ಒಂದು ಪೋರ್ಟ್' (one-port-per-session) ಎನ್ನುವ ಮಾದರಿಯೇ ಆಗಿತ್ತು. ಹೆಚ್ಚಿನ ಸಂವಹನಗಳು ಏಕಕಾಲದಲ್ಲಿ ನಡೆಯುವಾಗ (high concurrency), ಅತ್ಯಂತ ದೊಡ್ಡ ಮಟ್ಟದ UDP ಪೋರ್ಟ್ ಶ್ರೇಣಿಗಳನ್ನು ಬಹಿರಂಗಪಡಿಸುವುದು ಮತ್ತು ನಿರ್ವಹಿಸುವುದು ಅನಿವಾರ್ಯವಾಗುತ್ತದೆ.
- ಕ್ಲೌಡ್ ಲೋಡ್ ಬ್ಯಾಲೆನ್ಸರ್ಗಳು ಮತ್ತು Kubernetes ಸೇವೆಗಳನ್ನು ಪ್ರತಿ ಸೇವೆಗೆ ಹತ್ತಾರು ಸಾವಿರ ಸಾರ್ವಜನಿಕ UDP ಪೋರ್ಟ್ಗಳಿಗಾಗಿ ವಿನ್ಯಾಸಗೊಳಿಸಲಾಗಿಲ್ಲ. ಪ್ರತಿಯೊಂದು ಹೆಚ್ಚುವರಿ ಪೋರ್ಟ್ ಶ್ರೇಣಿಯು ಲೋಡ್ ಬ್ಯಾಲೆನ್ಸರ್ ಕಾನ್ಫಿಗ್, ಹೆಲ್ತ್ ಚೆಕಿಂಗ್, ಫೈರ್ವಾಲ್ ಪಾಲಿಸಿ ಮತ್ತು ರೋಲ್ಔಟ್ ಸುರಕ್ಷತೆಯಲ್ಲಿ ಕಾರ್ಯಾಚರಣೆಯ ಸಂಕೀರ್ಣತೆಯನ್ನು ಹೆಚ್ಚಿಸುತ್ತದೆ.3
- ದೊಡ್ಡ ಮಟ್ಟದ UDP ಪೋರ್ಟ್ ಶ್ರೇಣಿಗಳು ಬಾಹ್ಯವಾಗಿ ತಲುಪಬಹುದಾದ ಪ್ರದೇಶವನ್ನು ವಿಸ್ತರಿಸುವುದರಿಂದ ಮತ್ತು ನೆಟ್ವರ್ಕ್ ಪಾಲಿಸಿಯನ್ನು ಆಡಿಟ್ ಮಾಡುವುದನ್ನು ಕಷ್ಟಕರವಾಗಿಸುವುದರಿಂದ ಇವುಗಳನ್ನು ಸುರಕ್ಷಿತವಾಗಿಡುವುದು ಸವಾಲಿನ ಕೆಲಸವಾಗಿದೆ.
- Kubernetes ನಲ್ಲಿ ಪಾಡ್ಗಳ ನಿರಂತರ ಸೇರ್ಪಡೆ, ತೆಗೆದುಹಾಕುವಿಕೆ ಮತ್ತು ಮರುಹಂಚಿಕೆಯಿಂದಾಗಿ, ಆಟೋಸ್ಕೇಲಿಂಗ್ಗೆ ಹೆಚ್ಚಿನ ಪೋರ್ಟ್ ಶ್ರೇಣಿಯನ್ನು ಕಾಯ್ದಿರಿಸುವ ಅಗತ್ಯವು ತಾಂತ್ರಿಕ ಸ್ಥಿತಿಸ್ಥಾಪಕತ್ವವನ್ನು ದುರ್ಬಲಗೊಳಿಸುತ್ತದೆ. ಈ ಪ್ರಕ್ರಿಯೆಯು ಪಾಡ್ಗಳ ಸ್ಥಿರತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ.4
ಇದೇ ಕಾರಣಕ್ಕಾಗಿ ಅನೇಕ WebRTC ಸಿಸ್ಟಮ್ಗಳು ಪ್ರತಿ ಸರ್ವರ್ಗೆ ಒಂದೇ UDP ಪೋರ್ಟ್ ಬಳಸುವತ್ತ ಸಾಗುತ್ತಿವೆ, ಮತ್ತು ಆ ಪೋರ್ಟ್ನ ಹಿಂದೆ ಅಪ್ಲಿಕೇಶನ್-ಮಟ್ಟದ ಡಿಮಲ್ಟಿಪ್ಲೆಕ್ಸಿಂಗ್ (demultiplexing) ವ್ಯವಸ್ಥೆಯನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳುತ್ತಿವೆ.5
ಪ್ರತಿ ಸರ್ವರ್ಗೆ ಒಂದೇ ಪೋರ್ಟ್ (Single-port-per-server) ವಿನ್ಯಾಸಗಳು ಪೋರ್ಟ್ಗಳ ಸಂಖ್ಯೆಯ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸುತ್ತವೆ, ಆದರೆ ಅವು ಎರಡನೇ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಚಯಿಸುತ್ತವೆ: ಒಂದು ಫ್ಲೀಟ್ನಲ್ಲಿ (fleet) ಪ್ರತಿ ಸೆಷನ್ನ ಮಾಲೀಕತ್ವವನ್ನು ಸಂರಕ್ಷಿಸುವುದು.
ICE ಮತ್ತು DTLS stateful ಪ್ರೋಟೋಕಾಲ್ಗಳು. session ರಚಿಸಿದ process ಅದೇ session ನ packet ಗಳನ್ನು ಮುಂದುವರಿದು ಸ್ವೀಕರಿಸಬೇಕು, ಆಗ ಅದು connectivity checks ಗಳನ್ನು ಮಾನ್ಯಗೊಳಿಸಬಹುದು, DTLS handshake ನ್ನು ಪೂರ್ಣಗೊಳಿಸಬಹುದು, SRTP ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡಬಹುದು, ಮತ್ತು ICE restart ಗಳಂತಹ ನಂತರದ session ಬದಲಾವಣೆಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಬಹುದು. ಅದೇ session ನ packet ಗಳು ಬೇರೆ process ಮೇಲೆ ಇಳಿದರೆ, setup ವಿಫಲವಾಗಬಹುದು ಅಥವಾ ಮೀಡಿಯಾ ಹಾಳಾಗಬಹುದು.
ಇದು ನಮಗೆ ಒಂದು ಸ್ಪಷ್ಟ ಗುರಿ ಕೊಟ್ಟಿತು: ಸಾರ್ವಜನಿಕ ಇಂಟರ್ನೆಟ್ಗೆ ಚಿಕ್ಕದು, ಸ್ಥಿರವಾದ UDP ಮೇಲ್ಮೈಯನ್ನು expose ಮಾಡುವುದು, ಮತ್ತು ಅದೇ ಸಮಯದಲ್ಲಿ ಪ್ರತಿಯೊಂದು packet ನ್ನೂ ಸಂಬಂಧಿತ WebRTC session ನ ಮಾಲಿಕತ್ವವಿರುವ transceiver ಗೆ ರೌಟ್ ಮಾಡುವುದು.
ನಾವು ಅಲ್ಲಿಗೆ ತಲುಪಲು ಹಲವಾರು ಮಾರ್ಗಗಳನ್ನು ಮೌಲ್ಯಮಾಪನ ಮಾಡಿದ್ದೇವೆ, ಇದರಲ್ಲಿ TURN (NAT ಸುತ್ತ ರಿಲೇಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಸಂಚರಿಸುವುದು) ಕೂಡ ಒಳಗೊಂಡಿದೆ. ಇಲ್ಲಿ ಎಡ್ಜ್ ರಿಲೇ ಗ್ರಾಹಕರ ಹಂಚಿಕೆಗಳನ್ನು (allocations) ಕೊನೆಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ಅವರ ಪರವಾಗಿ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮುಂದಕ್ಕೆ ಕಳುಹಿಸುತ್ತದೆ.2
Approach | Pros | Cons |
Unique IP:port per session (also known as native direct UDP) | Direct client-to-server media path No forwarding layer in the data path | Requires one public UDP port per session Large port ranges are difficult to expose and secure Poor fit for Kubernetes and cloud load balancers |
Unique IP:port per server | Much smaller public UDP footprint than per-session exposure One shared socket per server can demultiplex many sessions | Works cleanly on a single host, but not across a shared load-balanced fleet by itself Session demultiplexing on a single host only helps after a packet reaches that host; across a load-balanced fleet, the first packet can still land on the wrong instance, so you still need a deterministic way to steer each session to the process that owns it |
TURN relay (protocol-terminating) | Clients only need to reach the TURN relay address and port Can centralize policy at the edge | TURN allocations add setup round trips Moving or recovering allocations across TURN servers is still difficult |
Stateless forwarder + stateful terminator (OpenAI’s relay + transceiver) | Small public UDP footprint Transceiver still owns the full WebRTC session | Adds one forwarding hop before media reaches the owning transceiver Requires custom coordination between relay and transceiver |
ನಾವು ಹೊರತಂದಿರುವ ಈ ಆರ್ಕಿಟೆಕ್ಚರ್ ಪ್ಯಾಕೆಟ್ ರೌಟಿಂಗ್ ಮತ್ತು ಪ್ರೊಟೊಕಾಲ್ ಟರ್ಮಿನೇಶನ್ ಅನ್ನು ಪ್ರತ್ಯೇಕಿಸುತ್ತದೆ. ಸೆಷನ್ ಸ್ಥಾಪನೆಗಾಗಿ ಸಿಗ್ನಲಿಂಗ್ ಟ್ರಾನ್ಸ್ಸೀವರ್ ಅನ್ನು ತಲುಪಿದರೆ, ಮೀಡಿಯಾ ರಿಲೇ ಮೂಲಕ ಪ್ರವೇಶಿಸುತ್ತದೆ, ಇದು ಸಣ್ಣ ಸಾರ್ವಜನಿಕ ಹೆಜ್ಜೆಗುರುತನ್ನು ಹೊಂದಿರುವ ಹಗುರವಾದ UDP ಫಾರ್ವರ್ಡ್ ಮಾಡುವ ಪದರವಾಗಿದೆ.
ರಿಲೇಯು ಮೀಡಿಯಾವನ್ನು ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡುವುದಿಲ್ಲ, ICE ಸ್ಟೇಟ್ ಮೆಷಿನ್ಗಳನ್ನು ನಡೆಸುವುದಿಲ್ಲ ಅಥವಾ ಕೋಡೆಕ್ ಮಾತುಕತೆಯಲ್ಲಿ ಭಾಗವಹಿಸುವುದಿಲ್ಲ. ಇದು ಒಂದು ಗಮ್ಯಸ್ಥಾನವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಅಗತ್ಯವಿರುವಷ್ಟು ಪ್ಯಾಕೆಟ್ ಮೆಟಾಡೇಟಾವನ್ನು ಓದುತ್ತದೆ, ನಂತರ ಆ ಸೆಷನ್ ಹೊಂದಿರುವ ಟ್ರಾನ್ಸ್ಸೀವರ್ಗೆ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಫಾರ್ವರ್ಡ್ ಮಾಡುತ್ತದೆ. ಟ್ರಾನ್ಸ್ಸೀವರ್ ಈಗಲೂ ಸಾಮಾನ್ಯ WebRTC ಫ್ಲೋ ಅನ್ನು ನೋಡುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಪ್ರೋಟೋಕಾಲ್ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಗ್ರಾಹಕರ ದೃಷ್ಟಿಕೋನದಿಂದ, WebRTC ಸೆಷನ್ನಲ್ಲಿ ಏನೂ ಬದಲಾಗುವುದಿಲ್ಲ.
ಈ ವ್ಯವಸ್ಥೆಯಲ್ಲಿ first-packet routing ಪ್ರಮುಖ ಹಂತವಾಗಿದೆ. packet path ಮೇಲೆಯೇ ಯಾವುದೇ session ಇನ್ನೂ ಅಸ್ತಿತ್ವದಲ್ಲಿರದಿದ್ದರೂ, relay ಕ್ಲೈಂಟ್ನ ಮೊದಲ packet ನ್ನು ರೌಟ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ; ಹೊರಗಿನ lookup service ಮೇಲೆ ನಿಲ್ಲುವುದರಿಂದಲ್ಲ.
ಪ್ರತಿಯೊಂದು WebRTC session ಈಗಾಗಲೇ ಒಂದು protocol-native routing hook ಅನ್ನು ಹೊತ್ತುಕೊಂಡಿರುತ್ತದೆ: ICE username fragment, ಅಥವಾ ufrag, ಇದು session setup ವೇಳೆ ವಿನಿಮಯಗೊಳ್ಳುವ ಮತ್ತು STUN connectivity checks ಗಳಲ್ಲಿ ಪುನರಾವರ್ತಿಸಲ್ಪಡುವ ಚಿಕ್ಕ ಗುರುತು. relay ಗಮ್ಯಸ್ಥಾನ cluster ಮತ್ತು ಮಾಲಿಕ transceiver ಅನ್ನು ಊಹಿಸಿಕೊಳ್ಳಲು ಸಾಕಾಗುವಷ್ಟು routing metadata ಅದರಲ್ಲಿರುವಂತೆ ನಾವು server-side ufrag ಅನ್ನು ರಚಿಸುತ್ತೇವೆ.
signaling ವೇಳೆ, transceiver session state ಅನ್ನು ಹಂಚಿಕೆಮಾಡಿ SDP answer ನಲ್ಲಿ shared relay VIP ಮತ್ತು UDP port ಅನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ. VIP ಎಂದರೆ relay fleet ಮುಂದೆ ಇರುವ virtual IP address; port ಜೊತೆ ಸೇರಿ ಇದು ಕ್ಲೈಂಟ್ಗೆ `203.0.113.10:3478` ಎಂಬಂತೆ ಒಂದು ಸ್ಥಿರ ಗಮ್ಯಸ್ಥಾನ ನೀಡುತ್ತದೆ, ಯದ್ವಾ ಅನೇಕ relay instances ಅದರ ಹಿಂದೆ ಇದ್ದರೂ. ಕ್ಲೈಂಟ್ನ ಮೊದಲ media-path packet ಸಾಮಾನ್ಯವಾಗಿ STUN (Session Traversal Utilities for NAT) binding request ಆಗಿದ್ದು, packets ಪ್ರಕಟಿತ address ಗೆ ತಲುಪಬಹುದೇ ಎಂದು ಪರಿಶೀಲಿಸಲು ICE ಇದನ್ನು ಬಳಸುತ್ತದೆ.
relay ಆ ಮೊದಲ STUN packet ನಿಂದ server ufrag ಓದಲು, routing hint ಡಿಕೋಡ್ ಮಾಡಲು, ಮತ್ತು packet ನ್ನು ಮಾಲಿಕ transceiver ಗೆ forward ಮಾಡಲು ಬೇಕಾದಷ್ಟು ಭಾಗವನ್ನು ಮಾತ್ರ parse ಮಾಡುತ್ತದೆ. ಪ್ರತಿಯೊಂದು transceiver shared UDP socket ಮೇಲೆ ಕೇಳುತ್ತಿರುತ್ತದೆ, ಅಂದರೆ ಪ್ರತಿ session ಗೆ ಒಂದು socket ಅಲ್ಲ, ಬದಲಿಗೆ internal IP:port ಗೆ bind ಮಾಡಲಾದ ಒಂದು operating system ಎಂಡ್ಪಾಯಿಂಟ್. relay ಕ್ಲೈಂಟ್ source IP:port ನಿಂದ ಆ transceiver destination ಗೆ ಒಂದು session ರಚಿಸಿದ ಬಳಿಕ, ನಂತರದ DTLS, RTP, ಮತ್ತು RTCP packets ufrag ಅನ್ನು ಮತ್ತೆ ಡಿಕೋಡ್ ಮಾಡದೇ ಆ session ಒಳಗೆ ಹರಿಯುತ್ತವೆ.
relay ನ session ಅನ್ನು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಅತಿ ಕನಿಷ್ಠವಾಗಿರಿಸಲಾಗಿದೆ; packet forwarding ಗೆ ಮಾಹಿತಿ ನೀಡುವ in-memory session, ಜೊತೆಗೆ monitoring ಗಾಗಿ ಅಗತ್ಯವಾದ counters ಮತ್ತು session expiration ಹಾಗೂ cleanup ಗಾಗಿ timers ಮಾತ್ರ ಇದರಲ್ಲಿ ಸೇರಿವೆ. ಈ ವಿನ್ಯಾಸದ ಆಯ್ಕೆ packet path ಮೇಲೆಯೇ packet routing ನ್ನು ನೇರವಾಗಿ ಉಳಿಸುತ್ತದೆ. relay ಮರುಪ್ರಾರಂಭವಾಗಿ session ಕಳೆದುಕೊಂಡರೆ, ಮುಂದಿನ STUN packet ufrag routing hint ನಿಂದ session ನ್ನು ಮರುನಿರ್ಮಿಸುತ್ತದೆ. ಇದನ್ನು ಇನ್ನಷ್ಟು ವಿಶ್ವಾಸಾರ್ಹಗೊಳಿಸಲು, route ಸ್ಥಾಪನೆಯಾದ ಕೂಡಲೆ <client IP + Port, transceiver IP + Port> ಮ್ಯಾಪಿಂಗ್ ಅನ್ನು ಹಿಡಿದುಿಡಲು Redis cache ಅನ್ನು ಬಳಸಲಾಗುತ್ತದೆ; ಹೀಗಾಗಿ ಮುಂದಿನ STUN packet ಬರುವ ಮೊದಲುಲೇ ಅದನ್ನು ಪುನಃಪಡೆಯಬಹುದು.
ಸಾರ್ವಜನಿಕ UDP ಮೇಲ್ಮೈಯನ್ನು ಚಿಕ್ಕ ಸಂಖ್ಯೆಯ ಸ್ಥಿರ ವಿಳಾಸಗಳು ಮತ್ತು ports ಗಳಿಗೆ ಇಳಿಸಿದ ನಂತರ, ಅದೇ relay ಮಾದರಿಯನ್ನು ಜಾಗತಿಕವಾಗಿ ನಿಯೋಜಿಸಲು ನಾವು ಸಾಧ್ಯವಾಯಿತು. Global Relay ಎಂದರೆ ಭೌಗೋಳಿಕವಾಗಿ ವಿತರಿಸಲ್ಪಟ್ಟ relay ingress points ಗಳ ನಮ್ಮ fleet; ಇವೆಲ್ಲವೂ ಒಂದೇ packet-forwarding ವರ್ತನೆಯನ್ನು ಜಾರಿಗೊಳಿಸುತ್ತವೆ.
ವಿಶಾಲ ಭೌಗೋಳಿಕ ingress ಮೊದಲ ಕ್ಲೈಂಟ್-ಟು-OpenAI hop ಅನ್ನು ಚಿಕ್ಕದಾಗಿಸುತ್ತದೆ, ಏಕೆಂದರೆ packet ಮೊದಲು ದೂರದ ಪ್ರದೇಶಕ್ಕೆ ಸಾರ್ವಜನಿಕ ಇಂಟರ್ನೆಟ್ ದಾಟುವುದಕ್ಕೆ ಬದಲಾಗಿ, ಬಳಕೆದಾರನಿಗೆ ಭೌಗೋಳಿಕವಾಗಿಯೂ network topology ದೃಷ್ಟಿಯಿಂದಲೂ ಸಮೀಪದ relay ಮೂಲಕ ನಮ್ಮ network ಗೆ ಪ್ರವೇಶಿಸಬಹುದು. ವ್ಯಾವಹಾರಿಕವಾಗಿ, ಟ್ರಾಫಿಕ್ ನಮ್ಮ backbone ತಲುಪುವ ಮೊದಲು ಇದು ಕಡಿಮೆ ಲೇಟೆನ್ಸಿ, ಕಡಿಮೆ jitter, ಮತ್ತು ತಪ್ಪಿಸಬಹುದಾದ ಕಡಿಮೆ loss bursts ಅನ್ನು ಅರ್ಥಮಾಡಿಸುತ್ತದೆ.6
signaling ಗಾಗಿ ನಾವು Cloudflare geo ಮತ್ತು proximity steering ಬಳಸುತ್ತೇವೆ; ಹೀಗಾಗಿ ಆರಂಭಿಕ HTTP ಅಥವಾ WebSocket ವಿನಂತಿ ಸಮೀಪದ transceiver cluster ಗೆ ತಲುಪುತ್ತದೆ. ವಿನಂತಿಯ ಸಂದರ್ಭವೇ session ನ ಸ್ಥಳವನ್ನೂ ಕ್ಲೈಂಟ್ಗೆ ಯಾವ Global Relay ingress point ಅನ್ನು ಪ್ರಕಟಿಸಬೇಕೆಂಬುದನ್ನೂ ನಿರ್ಧರಿಸುತ್ತದೆ. SDP answer Global Relay ವಿಳಾಸವನ್ನು ಒದಗಿಸುತ್ತದೆ, ಮತ್ತು ufrag ನಲ್ಲಿ Global Relay ಮೀಡಿಯಾವನ್ನು ನಿಗದಿತ cluster ಗೆ ರೌಟ್ ಮಾಡಲು ಹಾಗೂ relay ಗಮ್ಯ transceiver ಗೆ ರೌಟ್ ಮಾಡಲು ಸಾಕಾದ ಮಾಹಿತಿ ಇರುತ್ತದೆ.
ಒಟ್ಟಾಗಿ, geo-steered signaling ಮತ್ತು Global Relay, session ಅನ್ನು ಒಂದೇ transceiver ಗೆ anchor ಮಾಡಿಟ್ಟುಕೊಂಡು, setup ಹಾಗೂ media ಎರಡನ್ನೂ ಸಮೀಪದ entry path ಮೇಲೆ ಇರಿಸುತ್ತವೆ. ಇದರಿಂದ signaling ಗಾಗಿ ಮತ್ತು ಮೊದಲ ICE connectivity check ಗಾಗಿ round-trip time ಕಡಿಮೆಯಾಗುತ್ತದೆ; ಅದು ಬಳಕೆದಾರ ಮಾತು ಆರಂಭಿಸಲು ಕಾಯುವ ಅವಧಿಯನ್ನು ನೇರವಾಗಿ ಚಿಕ್ಕದಾಗಿಸುತ್ತದೆ.
ನಾವು relay service ಅನ್ನು Go ನಲ್ಲಿ ಬರೆದೆವು ಮತ್ತು ಜಾರಿಯನ್ನು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಸೀಮಿತವಾಗಿಟ್ಟೆವು. Linux ನಲ್ಲಿ, kernel networking stack ಯಂತ್ರದ network interface ನಿಂದ UDP packets ಸ್ವೀಕರಿಸಿ ಅವುಗಳನ್ನು socket ಗೆ ತಲುಪಿಸುತ್ತದೆ; IP:Port ಗೆ bind ಮಾಡಿದ ನಂತರ process ಓದುವ operating system ಎಂಡ್ಪಾಯಿಂಟ್ ಅದಾಗಿದೆ. relay userspace ನಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಸಾಮಾನ್ಯ Go process ಆ socket ನಿಂದ packet headers ಓದಿ, ಸ್ವಲ್ಪ flow state ನ್ನು ನವೀಕರಿಸಿ, WebRTC terminate ಮಾಡದೇ packets ಅನ್ನು forward ಮಾಡುತ್ತದೆ. userspace process ಗೆ ನೇರವಾಗಿ network queues poll ಮಾಡಲು ಅವಕಾಶ ನೀಡುವ, ಆದರೆ ಕಾರ್ಯಾಚರಣಾತ್ಮಕ ಸಂಕೀರ್ಣತೆಯನ್ನೂ ಹೆಚ್ಚಿಸುವ ಯಾವುದೇ kernel-bypass framework ನಮಗೆ ಬೇಕಾಗಲಿಲ್ಲ.
ಮುಖ್ಯ ವಿನ್ಯಾಸ ಆಯ್ಕೆಗಳು.
- ಪ್ರೋಟೋಕಾಲ್ ಟರ್ಮಿನೇಶನ್ ಇಲ್ಲ: relay STUN headers/ufrag ಅನ್ನು ಮಾತ್ರ parse ಮಾಡುತ್ತದೆ; ನಂತರದ DTLS, RTP, ಮತ್ತು RTCP ಗಾಗಿ cached state ಬಳಸುತ್ತದೆ, ಹೀಗಾಗಿ packets opaque ಆಗಿ ಉಳಿಯುತ್ತವೆ.
- ತಾತ್ಕಾಲಿಕ ಸ್ಥಿತಿ: flow state ಮತ್ತು observability ಗಾಗಿ ಕ್ಲೈಂಟ್ ವಿಳಾಸದಿಂದ transceiver destination ವರೆಗೆ ಚಿಕ್ಕದು, short-timeout, in-memory map ಅನ್ನು ಇದು ನಿರ್ವಹಿಸುತ್ತದೆ.
- pls translate to kannadaಸಮಾನಾಂತರ ಸ್ಕೇಲೆಬಿಲಿಟಿ (Horizontal scalability): ಲೋಡ್ ಬ್ಯಾಲೆನ್ಸರ್ನ ಹಿಂದೆ ಏಕಕಾಲದಲ್ಲಿ ಅನೇಕ ರಿಲೇ ಇನ್ಸ್ಟೆನ್ಸ್ಗಳು ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ. ಇಲ್ಲಿನ ಸ್ಥಿತಿಯು (state) ಕಠಿಣವಾದ WebRTC ಸ್ಥಿತಿಯಲ್ಲದ ಕಾರಣ, ಮರುಪ್ರಾರಂಭಗಳು (restarts) ಕನಿಷ್ಠ ಟ್ರಾಫಿಕ್ ಇಳಿಕೆಗೆ ಕಾರಣವಾಗುತ್ತವೆ ಮತ್ತು ಹರಿವಿನ ಮರುಸ್ಥಾಪನೆಯು (flow recovery) ವೇಗವಾಗಿ ನಡೆಯುತ್ತದೆ.
ಕಾರ್ಯಕ್ಷಮತಾ ಕ್ರಮಗಳು.
SO_REUSEPORTಎಂಬುದು Linux socket option ಆಗಿದ್ದು, ಅದೇ ಯಂತ್ರದಲ್ಲಿ ಹಲವು relay workers ಗಳು ಅದೇ UDP port ಗೆ bind ಆಗಲು ಅವಕಾಶ ನೀಡುತ್ತದೆ. ನಂತರ kernel ಒಳಬರುವ packets ಗಳನ್ನು ಆ workers ಗಳ ನಡುವೆ ಹಂಚುತ್ತದೆ; ಇದರಿಂದ ಒಂದು single read-loop bottleneck ತಪ್ಪುತ್ತದೆ.runtime.LockOSThreadಪ್ರತಿಯೊಂದು UDP-reading goroutine ಅನ್ನು ಒಂದು ನಿರ್ದಿಷ್ಟ OS thread ಗೆ pin ಮಾಡುತ್ತದೆ.SO_REUSEPORTಜೊತೆ ಸೇರಿ ಬಳಸಿದಾಗ, ಅದೇ flow ನ packets (source ಮತ್ತು destination IP:Port ಜೊತೆಗೆ protocol) ಅದೇ CPU core ಮೇಲೆಯೇ ಉಳಿಯುವ ಪ್ರವೃತ್ತಿ ಕಂಡುಬರುತ್ತದೆ; ಇದರಿಂದ cache locality ಸುಧಾರಿಸುತ್ತದೆ ಮತ್ತು context switching ಕಡಿಮೆಯಾಗುತ್ತದೆ.- ಮುಂಚಿತವಾಗಿ ಹಂಚಿದ buffers ಮತ್ತು ಕನಿಷ್ಠ copying, Go ಯಲ್ಲಿ garbage collection ತಪ್ಪಿಸಲು parsing ಹಾಗೂ allocation overhead ಅನ್ನು ಕಡಿಮೆಯಾಗಿ ಇಡುತ್ತವೆ.
ಈ ಜಾರಿಗೊಳಿಕೆ ನಮ್ಮ ಜಾಗತಿಕ ರಿಯಲ್-ಟೈಮ್ ಮೀಡಿಯಾ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಅಲ್ಪ relay ಹೆಜ್ಜೆಗುರುತುಗಳೊಂದಿಗೆ ನಿರ್ವಹಿಸಿತು; ಆದ್ದರಿಂದ kernel bypass ದಾರಿಗೆ ಹೋಗುವ ಬದಲು ನಾವು ಸರಳ ವಿನ್ಯಾಸವನ್ನೇ ಉಳಿಸಿಕೊಂಡೆವು.
Kubernetes ನಲ್ಲಿ ಸಾವಿರಾರು UDP ಪೋರ್ಟ್ಗಳನ್ನು ಬಹಿರಂಗಪಡಿಸದೆಯೇ WebRTC ಮೀಡಿಯಾವನ್ನು ಚಲಾಯಿಸಲು ಈ ವಿನ್ಯಾಸವು ಸಹಾಯ ಮಾಡುತ್ತದೆ, ಇದು ಸುಲಭವಾದ ಭದ್ರತೆ ಮತ್ತು ಲೋಡ್ ಬ್ಯಾಲೆನ್ಸಿಂಗ್ಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಈ SFU-ರಹಿತ ವಿಧಾನವು ಮೂಲಸೌಕರ್ಯವನ್ನು ಪ್ರಮಾಣಿತ WebRTC ನಡವಳಿಕೆಯನ್ನು ಸಂರಕ್ಷಿಸುವಾಗ ದಕ್ಷತೆಯಿಂದ ವಿಸ್ತರಿಸಲು (scale) ಸಹಾಯ ಮಾಡುತ್ತದೆ. ಹೆಚ್ಚಿನ ವಿವರಗಳಿಗಾಗಿ, blog.google.com ಅನ್ನು ಸಂದರ್ಶಿಸಿ.
ವಿಸ್ತೃತ ಪಾಠವೆಂದರೆ ಸಂಕೀರ್ಣತೆಯನ್ನು ಸೇರಿಸಲು ಅತ್ಯುತ್ತಮ ಸ್ಥಳವು ಒಂದು ತೆಳುವಾದ routing layer ಆಗಿದೆ; ಪ್ರತಿಯೊಂದು backend service ಯಲ್ಲೂ ಅಲ್ಲ, ಮತ್ತು custom client ವರ್ತನೆಯಲ್ಲೂ ಅಲ್ಲ. protocol-native field ಒಳಗೆ routing metadata ಅನ್ನು encode ಮಾಡಿದುದರಿಂದ ನಮಗೆ deterministic first-packet routing, ಚಿಕ್ಕ public UDP footprint, ಮತ್ತು ಜಗತ್ತಿನಾದ್ಯಂತ ಬಳಕೆದಾರರ ಸಮೀಪದಲ್ಲಿ ingress ಇಡುವಷ್ಟು ಲವಚಿಕತೆ ದೊರೆಯಿತು.
ಕೆಲವು ಆಯ್ಕೆಗಳು ವಿಶೇಷವಾಗಿ ಮಹತ್ವದ್ದಾಗಿದ್ದವು.
- ಎಡ್ಜ್ನಲ್ಲಿ ಪ್ರೋಟೋಕಾಲ್ semantics ಅನ್ನು ಉಳಿಸಿಕೊಳ್ಳಿ. ಕ್ಲೈಂಟ್ಗಳು ಇನ್ನೂ ಮಾನಕ WebRTC ನಲ್ಲೇ ಮಾತನಾಡುತ್ತವೆ; ಇದು ಬ್ರೌಸರ್ ಮತ್ತು ಮೊಬೈಲ್ ಪರಸ್ಪರ ಕಾರ್ಯನಿರ್ವಹಣೆಯನ್ನು ಅಕ್ಷುಣ್ಣವಾಗಿರಿಸುತ್ತದೆ.
- ಹಾರ್ಡ್ ಸೆಷನ್ ಸ್ಟೇಟ್ಗಳನ್ನು (hard session states) ಒಂದೇ ಸ್ಥಳದಲ್ಲಿ ಇರಿಸಿ. ಟ್ರಾನ್ಸ್ಸೀವರ್ ICE, DTLS, SRTP ಮತ್ತು ಸೆಷನ್ ಲೈಫ್ಸೈಕಲ್ ಅನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ; ರಿಲೇ ಕೇವಲ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಫಾರ್ವರ್ಡ್ ಮಾಡುತ್ತದೆ.
- setup ನಲ್ಲಿ ಈಗಾಗಲೇ ಇರುವ ಮಾಹಿತಿಯ ಮೇಲೇ ರೌಟ್ ಮಾಡಿ. ICE ufrag ನಮಗೆ hot-path lookup ಅವಲಂಬನೆಯನ್ನು ಸೇರಿಸದೇ first-packet routing hook ನೀಡಿತು.
- kernel bypass ಕಡೆ ಹೋಗುವ ಮೊದಲು ಸಾಮಾನ್ಯ ಸಂದರ್ಭಕ್ಕಾಗಿ optimize ಮಾಡಿ.
SO_REUSEPORT, thread pinning, ಮತ್ತು low-allocation parsing ಗಳ ಜಾಗರೂಕ ಬಳಕೆಯೊಂದಿಗೆ ಇರುವ ಸೀಮಿತ Go ಜಾರಿ ನಮ್ಮ ವರ್ಕ್ಲೋಡ್ಗೆ ಸಾಕಾಯಿತು.
ಮೂಲಸೌಕರ್ಯವು ಲೇಟೆನ್ಸಿಯನ್ನು ಗೋಚರಿಸದಂತೆ ಅನುಭವಿಸುವಂತೆ ಮಾಡಿದಾಗ ಮಾತ್ರ ರಿಯಲ್-ಟೈಮ್ ವಾಯ್ಸ್ AI ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ನಮ್ಮ ಪಾಲಿಗೆ, ಅದೇನೆಂದರೆ WebRTC ನಿಂದ ಕ್ಲೈಂಟ್ಗಳು ನಿರೀಕ್ಷಿಸುವುದನ್ನು ಬದಲಿಸದೇ, ನಮ್ಮ WebRTC ನಿಯೋಜನೆಯ ರೂಪವನ್ನು ಬದಲಿಸುವುದು.
ಲೇಖಕ
ಉಲ್ಲೇಖಗಳು
2. GitHub - l7mp/stunner: WebRTC ಗಾಗಿ Kubernetes ಮೀಡಿಯಾ ಗೇಟ್ವೇ(ಹೊಸ ಕಿಟಕಿಯಲ್ಲಿ ತೆರೆಯುತ್ತದೆ)
3. ಸಂಕ್ಷಿಪ್ತವಾಗಿ WebRTC ಪೋರ್ಟ್ಗಳು [ಉದಾಹರಣೆಗಳು] - BlogGeek.me(ಹೊಸ ಕಿಟಕಿಯಲ್ಲಿ ತೆರೆಯುತ್ತದೆ)
4. Kubernetes ಗೆ ನಿಯೋಜಿಸಿ - LiveKit ಡಾಕ್ಸ್(ಹೊಸ ಕಿಟಕಿಯಲ್ಲಿ ತೆರೆಯುತ್ತದೆ)
6. Cloudflare Calls: ಸಂಪೂರ್ಣ ಕೆಳಮಟ್ಟದವರೆಗೂ ಮಿಲಿಯನ್ಗಟ್ಟಲೆ cascading trees(ಹೊಸ ಕಿಟಕಿಯಲ್ಲಿ ತೆರೆಯುತ್ತದೆ)


