ΠΠ΄ΡΠ°Π²Π΅ΠΉΡΠ΅ Π½Π° Π²ΡΠΈΡΠΊΠΈ. ΠΡΠΈΡΡΠ΅Π»ΠΈ, ΡΠΏΠΎΠ΄Π΅Π»ΡΠΌΠ΅ Ρ Π²Π°Ρ ΠΏΡΠ΅Π²ΠΎΠ΄ Π½Π° ΡΡΠ°ΡΠΈΡ, ΠΏΠΎΠ΄Π³ΠΎΡΠ²Π΅Π½ ΡΠΏΠ΅ΡΠΈΠ°Π»Π½ΠΎ Π·Π° ΡΡΡΠ΄Π΅Π½ΡΠΈΡΠ΅ ΠΎΡ ΠΊΡΡΡΠ° . ΠΠ° Π·Π°ΠΏΠΎΡΠ²Π°ΠΌΠ΅!

Apache Beam ΠΈ DataFlow Π·Π° ΡΠ΅Π°Π»Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΈ ΠΏΠΎΡΠΎΡΠΈ
ΠΠ½Π΅ΡΠ½Π°ΡΠ° ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΡ Π΅ Π±Π°Π·ΠΈΡΠ°Π½Π° Π½Π° Π·Π°Π΄Π°ΡΠ°, Ρ ΠΊΠΎΡΡΠΎ Π½Π°ΡΠΊΠΎΡΠΎ ΡΠ΅ Π·Π°Π½ΠΈΠΌΠ°Π²Π°Ρ Π½Π° ΡΠ°Π±ΠΎΡΠ°. ΠΡΡ Π½Π°ΠΈΡΡΠΈΠ½Π° ΡΠ°Π΄ΠΎΡΡΠ΅Π½, ΡΠ΅ ΠΌΠΎΠ³Π° Π΄Π° Ρ ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌ ΠΈ Π΄Π° ΠΎΠΏΠΈΡΠ° ΡΠ²ΡΡΡΠ΅Π½Π°ΡΠ° ΡΠ°Π±ΠΎΡΠ° Π²ΡΠ² ΡΠΎΡΠΌΠ°Ρ Π½Π° Π±Π»ΠΎΠ³ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΡ, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠΎΠ²Π° ΠΌΠΈ Π΄Π°Π΄Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ Π΄Π° ΡΠ΅ Π·Π°Π½ΠΈΠΌΠ°Π²Π°ΠΌ Ρ Π΄Π°ΡΠ° ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΠΈΠ½Π³, Π° ΡΡΡΠΎ ΡΠ°ΠΊΠ° Π΄Π° Π½Π°ΠΏΡΠ°Π²Ρ Π½Π΅ΡΠΎ, ΠΊΠΎΠ΅ΡΠΎ Π±ΠΈ Π±ΠΈΠ»ΠΎ Π½Π°ΠΈΡΡΠΈΠ½Π° ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π·Π° ΠΌΠΎΡ ΠΎΡΠ±ΠΎΡ. ΠΠ΅ΠΎΡΠ΄Π°Π²Π½Π° ΠΎΡΠΊΡΠΈΡ , ΡΠ΅ Π² Π½Π°ΡΠΈΡΠ΅ ΡΠΈΡΡΠ΅ΠΌΠΈ ΡΠ΅ ΡΡΡ ΡΠ°Π½ΡΠ²Π° Π΄ΠΎΡΡΠ° Π³ΠΎΠ»ΡΠΌ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ Π»ΠΎΠ³, ΡΠ²ΡΡΠ·Π°Π½ Ρ Π΅Π΄ΠΈΠ½ ΠΎΡ Π½Π°ΡΠΈΡΠ΅ ΠΏΡΠΎΠ΄ΡΠΊΡΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ Π΄Π°Π½Π½ΠΈ. ΠΠΊΠ°Π·Π° ΡΠ΅, ΡΠ΅ Π½ΠΈΠΊΠΎΠΉ Π½Π΅ Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π» ΡΠ΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ, Π·Π°ΡΠΎΠ²Π° Π²Π΅Π΄Π½Π°Π³Π° ΡΠ΅ Π·Π°ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ²Π°Ρ ΠΊΠ°ΠΊΠ²ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π½Π°ΡΡΠΈΠΌ, Π°ΠΊΠΎ Π·Π°ΠΏΠΎΡΠ½Π΅ΠΌ ΡΠ΅Π΄ΠΎΠ²Π½ΠΎ Π΄Π° Π³ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅. ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠΎΠ²Π°, Π½Π° ΠΏΡΡΡ ΡΡΠΎΡΡ Π° Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°. ΠΡΡΠ²ΠΈΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Π±Π΅ΡΠ΅, ΡΠ΅ Π΄Π°Π½Π½ΠΈΡΠ΅ ΡΠ΅ ΡΡΡ ΡΠ°Π½ΡΠ²Π°Ρ Π° Π² ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅, ΠΊΠΎΠΈΡΠΎ Π½Π΅ Π±ΡΡ Π° Π΄ΠΎΡΡΡΠΏΠ½ΠΈ Π·Π° ΠΌΠΈΠ³Π½ΠΎΠ²Π΅Π½ Π°Π½Π°Π»ΠΈΠ·. ΠΡΠΎΡΠΈΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Π±Π΅ΡΠ΅, ΡΠ΅ ΡΠ΅ Π±ΡΡ Π° Π·Π°ΠΏΠ°Π·Π΅Π½ΠΈ Π² Π·Π°ΡΠ²ΠΎΡΠ΅Π½Π° ΡΠΈΡΡΠ΅ΠΌΠ°, Π·Π°ΡΠΎΠ²Π° Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ Π½ΠΈΡΠΎ Π΅Π΄ΠΈΠ½ ΠΎΡ ΠΌΠΎΠΈΡΠ΅ Π»ΡΠ±ΠΈΠΌΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ Π·Π° Π°Π½Π°Π»ΠΈΠ· Π½Π° Π΄Π°Π½Π½ΠΈ.
Π’ΡΡΠ±Π²Π°ΡΠ΅ Π΄Π° ΡΠ΅ΡΠ° ΠΊΠ°ΠΊ Π΄Π° Π½Π°ΠΏΡΠ°Π²Ρ Π΄ΠΎΡΡΡΠΏΠ° Π·Π° Π½Π°Ρ ΠΏΠΎ-Π»Π΅ΡΠ΅Π½ ΠΈ Π΄Π° Π²Π½Π΅ΡΠ° Π½ΡΠΊΠ°ΠΊΠ²Π° ΡΡΠΎΠΉΠ½ΠΎΡΡ, Π²Π½Π΅Π΄ΡΡΠ²Π°ΠΉΠΊΠΈ ΡΠΎΠ·ΠΈ ΠΈΠ·ΡΠΎΡΠ½ΠΈΠΊ Π½Π° Π΄Π°Π½Π½ΠΈ Π² Π½ΡΠΊΠΎΠΈ ΠΎΡ Π½Π°ΡΠΈΡΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π·Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Ρ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈΡΠ΅. Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ ΠΏΠΎΠΌΠΈΡΠ»ΠΈΡ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ Π²ΡΠ΅ΠΌΠ΅, ΡΠ΅ΡΠΈΡ Π΄Π° ΠΈΠ·Π³ΡΠ°Π΄Ρ ΠΏΠΎΡΠΎΠΊ Π·Π° ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅ Π½Π° ΡΠ΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ Π² ΠΎΠ±Π»Π°ΡΠ½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ, Π·Π° Π΄Π° ΠΌΠΎΠΆΠ΅ΠΌ Π°Π· ΠΈ Π΅ΠΊΠΈΠΏΡΡ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΠΌ Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΡΡΡ ΠΈ Π΄Π° Π·Π°ΠΏΠΎΡΠ½Π΅ΠΌ Π΄Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°ΠΌΠ΅ Π½ΡΠΊΠ°ΠΊΠ²ΠΈ ΠΈΠ·Π²ΠΎΠ΄ΠΈ. Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ Π·Π°Π²ΡΡΡΠΈΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡΡΠ° ΠΏΠΎ Data Engineering Π² Coursera ΠΏΡΠ΅Π΄ΠΈ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ Π²ΡΠ΅ΠΌΠ΅, Π±ΡΡ Π½Π΅ΡΡΡΠΏΠ΅Π»ΠΈΠ² Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ° Π½ΡΠΊΠΎΠΈ ΠΎΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈΡΠ΅ ΠΎΡ ΠΊΡΡΡΠ°.
Π’Π°ΠΊΠ° ΡΠ΅ Π½Π°Π»ΠΈΡΠΈΠ΅ΡΠΎ Π½Π° Π΄Π°Π½Π½ΠΈ Π² ΠΎΠ±Π»Π°ΡΠ½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°ΡΠ΅ ΡΠ°Π·ΡΠΌΠ΅Π½ Π½Π°ΡΠΈΠ½ Π·Π° ΡΠ΅ΡΠ°Π²Π°Π½Π΅ Π½Π° ΠΏΡΡΠ²ΠΈΡ ΠΌΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌ, Π½ΠΎ ΠΊΠ°ΠΊΠ²ΠΎ Π΄Π° Π½Π°ΠΏΡΠ°Π²Ρ Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Π½ΠΎΠΌΠ΅Ρ 2? ΠΠ° ΡΠ°ΡΡΠΈΠ΅, ΠΈΠΌΠ°ΡΠ΅ Π½Π°ΡΠΈΠ½ Π΄Π° ΠΏΡΠ΅Π½Π΅ΡΠ° ΡΠ΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ Π² ΡΡΠ΅Π΄Π°, ΠΊΡΠ΄Π΅ΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π΄Π° ΠΏΠΎΠ»ΡΡΠ° Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ ΠΊΠ°ΡΠΎ Python ΠΈ Google Cloud Platform (GCP). ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠΎΠ²Π°, ΡΠΎΠ²Π° Π±Π΅ΡΠ΅ Π΄ΡΠ»ΡΠ³ ΠΏΡΠΎΡΠ΅Ρ, ΡΠ°ΠΊΠ° ΡΠ΅ ΡΡΡΠ±Π²Π°ΡΠ΅ Π΄Π° Π½Π°ΠΏΡΠ°Π²Ρ Π½Π΅ΡΠΎ, ΠΊΠΎΠ΅ΡΠΎ Π΄Π° ΠΌΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π΄Π° ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°ΡΠ°, Π΄ΠΎΠΊΠ°ΡΠΎ ΡΠ°ΠΊΠ°Ρ ΠΏΡΠΈΠΊΠ»ΡΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΠΏΡΠ΅Π½ΠΎΡΠ° Π½Π° Π΄Π°Π½Π½ΠΈΡΠ΅. Π Π΅ΡΠ΅Π½ΠΈΠ΅ΡΠΎ, Π΄ΠΎ ΠΊΠΎΠ΅ΡΠΎ ΡΡΠΈΠ³Π½Π°Ρ , Π±Π΅ΡΠ΅ Π΄Π° ΡΡΠ·Π΄Π°ΠΌ ΡΠ°Π»ΡΠΈΠ²ΠΈ Π΄Π°Π½Π½ΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° Faker Π² Python. ΠΠΈΠΊΠΎΠ³Π° ΠΏΡΠ΅Π΄ΠΈ Π½Π΅ Π±ΡΡ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π» ΡΠ°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°, Π½ΠΎ Π±ΡΡΠ·ΠΎ ΠΎΡΡΠ·Π½Π°Ρ ΠΊΠΎΠ»ΠΊΠΎ Π΅ ΠΏΠΎΠ»Π΅Π·Π½Π°. ΠΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠΎΠ·ΠΈ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΌΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π΄Π° Π·Π°ΠΏΠΎΡΠ½Π° Π΄Π° ΠΏΠΈΡΠ° ΠΊΠΎΠ΄ ΠΈ Π΄Π° ΡΠ΅ΡΡΠ²Π°ΠΌ ΠΏΠΎΡΠΎΠΊΠ° Π±Π΅Π· ΡΠ΅Π°Π»Π½ΠΈ Π΄Π°Π½Π½ΠΈ.
Π‘ ΠΎΠ³Π»Π΅Π΄ Π½Π° Π²ΡΠΈΡΠΊΠΎ ΠΊΠ°Π·Π°Π½ΠΎ Π΄ΠΎΡΡΠΊ, Π² ΡΠΎΠ·ΠΈ ΠΏΠΎΡΡ ΡΠ΅ ΡΠ°Π·ΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊ ΠΏΠΎΡΡΡΠΎΠΈΡ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΠΏΠΎ-Π³ΠΎΡΠ΅ ΠΏΠΎΡΠΎΠΊ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ Π½ΡΠΊΠΎΠΈ ΠΎΡ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈΡΠ΅, Π½Π°Π»ΠΈΡΠ½ΠΈ Π² GCP. ΠΠΎ-ΡΠΏΠ΅ΡΠΈΠ°Π»Π½ΠΎ, ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ Apache Beam (Python Π²Π΅ΡΡΠΈΡ), Dataflow, Pub/Sub ΠΈ Big Query Π·Π° ΡΡΠ±ΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ ΠΆΡΡΠ½Π°Π»ΠΈ, ΡΡΠ°Π½ΡΡΠΎΡΠΌΠΈΡΠ°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ ΠΈ ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅ Π½Π° ΡΡΡ Π² Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ Π·Π° ΠΏΠΎ-Π½Π°ΡΠ°ΡΡΡΠ΅Π½ Π°Π½Π°Π»ΠΈΠ·. Π ΠΌΠΎΡ ΡΠ»ΡΡΠ°ΠΉ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠ° ΠΌΠΈ Π±Π΅ΡΠ΅ ΡΠ°ΠΌΠΎ ΠΏΠ°ΠΊΠ΅ΡΠ½Π°ΡΠ° ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΎΡΡ Π½Π° Beam, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π΄Π°Π½Π½ΠΈΡΠ΅ ΠΌΠΈ Π½Π΅ ΠΈΠ΄Π²Π°Ρ Π° Π² ΡΠ΅Π°Π»Π½ΠΎ Π²ΡΠ΅ΠΌΠ΅, ΡΠ°ΠΊΠ° ΡΠ΅ Pub/Sub Π½Π΅ Π±Π΅ΡΠ΅ Π½ΡΠΆΠ΅Π½. ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠΎΠ²Π°, ΡΠ΅ ΡΠ΅ ΡΠΏΡΠ° ΠΈ Π½Π° ΠΏΠΎΡΠΎΠΊΠΎΠ²Π°ΡΠ° Π²Π΅ΡΡΠΈΡ, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠΎΠ²Π° Π΅ Π½Π΅ΡΠΎ, Ρ ΠΊΠΎΠ΅ΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠ΅ ΡΡΠ΅ΡΠ½Π΅ΡΠ΅ Π½Π° ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°.
ΠΡΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² GCP ΠΈ Apache Beam
Google Cloud Platform ΠΏΡΠ΅Π΄Π»Π°Π³Π° Π½Π°Π±ΠΎΡ ΠΎΡ Π½Π°ΠΈΡΡΠΈΠ½Π° ΠΏΠΎΠ»Π΅Π·Π½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ Π·Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈ Π΄Π°Π½Π½ΠΈ. ΠΡΠΎ Π½ΡΠΊΠΎΠΈ ΠΎΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈΡΠ΅, ΠΊΠΎΠΈΡΠΎ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ:
- Π΅ ΡΡΠ»ΡΠ³Π° Π·Π° ΠΎΠ±ΠΌΠ΅Π½ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ° ΠΌΠΎΠ΄Π΅Π»Π° ΠΠ·Π΄Π°ΡΠ΅Π»-ΠΠ±ΠΎΠ½Π°Ρ, ΠΊΠΎΡΡΠΎ Π½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ Π΄Π°Π½Π½ΠΈ Π² ΡΠ΅Π°Π»Π½ΠΎ Π²ΡΠ΅ΠΌΠ΅.
- Π΅ ΡΡΠ»ΡΠ³Π°, ΠΊΠΎΡΡΠΎ ΠΎΠΏΡΠΎΡΡΡΠ²Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ΡΠΎ Π½Π° ΠΏΠΎΡΠΎΡΠΈ Π·Π° Π΄Π°Π½Π½ΠΈ ΠΈ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎ ΡΠ°Π·ΡΠ΅ΡΠ°Π²Π° Π·Π°Π΄Π°ΡΠΈ ΠΊΠ°ΡΠΎ ΠΌΠ°ΡΠ°Π±ΠΈΡΠ°Π½Π΅ Π½Π° ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΠ°ΡΠ°, ΠΊΠΎΠ΅ΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π²Π°, ΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΡΠ΅ ΡΡΡΡΠ΅Π΄ΠΎΡΠΎΡΠΈΠΌ ΡΠ°ΠΌΠΎ Π²ΡΡΡ Ρ Π½Π°ΠΏΠΈΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΠΊΠΎΠ΄Π° Π·Π° Π½Π°ΡΠΈΡ ΠΏΠΎΡΠΎΠΊ.
- Π΅ ΠΎΠ±Π»Π°ΡΠ½ΠΎ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ Π·Π° Π΄Π°Π½Π½ΠΈ. ΠΠΊΠΎ ΡΡΠ΅ Π·Π°ΠΏΠΎΠ·Π½Π°ΡΠΈ Ρ Π΄ΡΡΠ³ΠΈ SQL Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ, Ρ BigQuery Π½Π΅ Π±ΠΈ ΡΡΡΠ±Π²Π°Π»ΠΎ Π΄Π° ΠΈΠΌΠ°ΡΠ΅ ΡΡΡΠ΄Π½ΠΎΡΡΠΈ.
- Π Π½Π°ΠΊΡΠ°Ρ, ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Apache Beam, ΠΏΠΎ-ΡΠΏΠ΅ΡΠΈΠ°Π»Π½ΠΎ, ΡΠ΅ ΡΠ΅ ΡΠΎΠΊΡΡΠΈΡΠ°ΠΌΠ΅ Π²ΡΡΡ Ρ Π²Π΅ΡΡΠΈΡΡΠ° Π½Π° Python Π·Π° ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° Π½Π°ΡΠΈΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ. Π’ΠΎΠ·ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ ΡΠ΅ Π½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ Π·Π° ΠΏΠΎΡΠΎΠΊΠΎΠ²Π° ΠΈΠ»ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠ½Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ°, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΠΈΠ½ΡΠ΅Π³ΡΠΈΡΠ° Ρ GCP. Π’ΠΎΠΉ Π΅ ΠΎΡΠΎΠ±Π΅Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π΅Π½ Π·Π° ΠΏΠ°ΡΠ°Π»Π΅Π»Π½Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΈ Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡ Π·Π° Π·Π°Π΄Π°ΡΠΈ, ΡΠ²ΡΡΠ·Π°Π½ΠΈ Ρ ΠΈΠ·Π²Π»ΠΈΡΠ°Π½Π΅, ΡΡΠ°Π½ΡΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΈ Π·Π°ΡΠ΅ΠΆΠ΄Π°Π½Π΅ (ETL), ΡΠ°ΠΊΠ° ΡΠ΅, Π°ΠΊΠΎ Π½ΠΈ ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΡΠ΅ΠΌΠ΅ΡΡΠ²Π°ΠΌΠ΅ Π΄Π°Π½Π½ΠΈ ΠΎΡ Π΅Π΄Π½ΠΎ ΠΌΡΡΡΠΎ Π½Π° Π΄ΡΡΠ³ΠΎ Ρ ΠΈΠ·Π²ΡΡΡΠ²Π°Π½Π΅ Π½Π° ΡΡΠ°Π½ΡΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΈΠ»ΠΈ ΠΈΠ·ΡΠΈΡΠ»Π΅Π½ΠΈΡ, Beam Π΅ Π΄ΠΎΠ±ΡΡ ΠΈΠ·Π±ΠΎΡ.
ΠΠ° GCP ΠΈΠΌΠ° Π³ΠΎΠ»ΡΠΌΠΎ ΡΠ°Π·Π½ΠΎΠΎΠ±ΡΠ°Π·ΠΈΠ΅ ΠΎΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ, ΡΠ°ΠΊΠ° ΡΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΡΡΡΠ΄Π½ΠΎ Π΄Π° ΡΠ΅ ΡΠ»Π΅Π΄ΡΡ Π²ΡΠΈΡΠΊΠΈ ΠΈ ΠΊΠ°ΠΊΠ²Π° Π΅ ΡΡΡ
Π½Π°ΡΠ° ΡΠ΅Π», Π½ΠΎ Π΅ΡΠΎ Π΅Π΄ΠΈΠ½ ΠΎΠ±Π·ΠΎΡ Π·Π° ΡΠΏΡΠ°Π²ΠΊΠ°.
Π GCP ΠΈΠΌΠ° ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ, ΡΠ°ΠΊΠ° ΡΠ΅ ΠΎΠ±Ρ
Π²Π°ΡΠ°Π½Π΅ΡΠΎ Π½Π° Π²ΡΠΈΡΠΊΠΈΡΠ΅, Π²ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ ΠΈ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΈΠΌ, ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΡΠ»ΠΎΠΆΠ½ΠΎ, Π½ΠΎ Π²ΡΠ΅ ΠΏΠ°ΠΊ ΠΊΡΠ°ΡΠΊΠΎ ΠΈΠ·Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π° ΡΠΏΡΠ°Π²ΠΊΠ°.
ΠΠΈΠ·ΡΠ°Π»ΠΈΠ·Π°ΡΠΈΡ Π½Π° Π½Π°ΡΠΈΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ
ΠΠ΅ΠΊΠ° Π²ΠΈΠ·ΡΠ°Π»ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΈΡΠ΅ Π½Π° Π½Π°ΡΠΈΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ Π½Π° ΡΠΈΡΡΠ½ΠΊΠ° 1. ΠΠ° Π²ΠΈΡΠΎΠΊΠΎ Π½ΠΈΠ²ΠΎ ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° ΡΡΠ±ΠΈΡΠ°ΠΌΠ΅ Π΄Π°Π½Π½ΠΈ ΠΎΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈ Π² ΡΠ΅Π°Π»Π½ΠΎ Π²ΡΠ΅ΠΌΠ΅, Π΄Π° Π³ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ²Π°ΠΌΠ΅ ΠΈ Π΄Π° Π³ΠΈ ΠΏΡΠ΅Π΄Π°Π²Π°ΠΌΠ΅ Π² BigQuery. ΠΠΎΠ³ΠΎΠ²Π΅ΡΠ΅ ΡΠ΅ ΡΡΠ·Π΄Π°Π²Π°Ρ, ΠΊΠΎΠ³Π°ΡΠΎ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈΡΠ΅ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²Π°Ρ Ρ ΠΏΡΠΎΠ΄ΡΠΊΡΠ°, ΠΈΠ·ΠΏΡΠ°ΡΠ°ΠΉΠΊΠΈ Π·Π°ΡΠ²ΠΊΠΈ Π½Π° ΡΡΡΠ²ΡΡΠ°, ΠΊΠΎΠΈΡΠΎ ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° ΡΠ΅ ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠ°Ρ. Π’Π΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ ΠΎΡΠΎΠ±Π΅Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΈ Π·Π° ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ ΠΊΠ°ΠΊ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈΡΠ΅ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²Π°Ρ Ρ Π½Π°ΡΠΈΡ ΠΏΡΠΎΠ΄ΡΠΊΡ ΠΈ Π΄Π°Π»ΠΈ ΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠ° ΠΏΡΠ°Π²ΠΈΠ»Π½ΠΎ. ΠΠ°ΡΠΎ ΡΡΠ»ΠΎ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΡΡ ΡΠ΅ ΡΡΠ΄ΡΡΠΆΠ° ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π΅ΡΠ°ΠΏΠΈ:
Beam ΠΏΡΠ°Π²ΠΈ ΡΠΎΠ·ΠΈ ΠΏΡΠΎΡΠ΅Ρ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΡ, Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ Π΄Π°Π»ΠΈ ΠΈΠΌΠ°ΠΌΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΈΠ·ΡΠΎΡΠ½ΠΈΠΊ Π½Π° Π΄Π°Π½Π½ΠΈ ΠΈΠ»ΠΈ ΡΠ°ΠΉΠ» CSV, ΠΈ ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° ΠΈΠ·Π²ΡΡΡΠΈΠΌ ΠΏΠ°ΠΊΠ΅ΡΠ½Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ°. ΠΠΎ-ΠΊΡΡΠ½ΠΎ ΡΠ΅ Π²ΠΈΠ΄ΠΈΡΠ΅, ΡΠ΅ Π² ΠΊΠΎΠ΄Π° ΠΈΠΌΠ° ΡΠ°ΠΌΠΎ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½ΠΈ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΠΏΡΠ΅Π²ΠΊΠ»ΡΡΠ²Π°Π½Π΅ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΡ . Π’ΠΎΠ²Π° Π΅ Π΅Π΄Π½ΠΎ ΠΎΡ ΠΏΡΠ΅Π΄ΠΈΠΌΡΡΠ²Π°ΡΠ° Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° Beam.

Π ΠΈΡΡΠ½ΠΎΠΊ 1: ΠΡΠ½ΠΎΠ²Π½ΠΈΡΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ Π·Π° Π΄Π°Π½Π½ΠΈ: ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ:
Π‘ΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΏΡΠ΅Π²Π΄ΠΎΠ΄Π°Π½Π½ΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° Faker
ΠΠ°ΠΊΡΠΎ Π²Π΅ΡΠ΅ ΡΠΏΠΎΠΌΠ΅Π½Π°Ρ , ΠΏΠΎΡΠ°Π΄ΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ Π΄Π°Π½Π½ΠΈ ΡΠ΅ΡΠΈΡ Π΄Π° ΡΡΠ·Π΄Π°ΠΌ ΠΏΡΠ΅Π²Π΄ΠΎΠ΄Π°Π½Π½ΠΈ Π² ΡΡΡΠΈΡ ΡΠΎΡΠΌΠ°Ρ, ΠΊΠ°ΠΊΡΠΎ ΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»Π½ΠΈΡΠ΅. Π’ΠΎΠ²Π° Π±Π΅ΡΠ΅ Π½Π°ΠΈΡΡΠΈΠ½Π° ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΡΠΏΡΠ°ΠΆΠ½Π΅Π½ΠΈΠ΅, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π΄Π° Π½Π°ΠΏΠΈΡΠ° ΠΊΠΎΠ΄ ΠΈ ΡΠ΅ΡΡΠ²Π°ΠΌ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΠ°, Π΄ΠΎΠΊΠ°ΡΠΎ ΠΎΡΠ°ΠΊΠ²Π°Ρ Π΄Π°Π½Π½ΠΈΡΠ΅. ΠΡΠ΅Π΄Π»Π°Π³Π°ΠΌ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌ Π½Π° Faker, Π°ΠΊΠΎ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΡΠ΅ ΠΊΠ°ΠΊΠ²ΠΎ Π΄ΡΡΠ³ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠΈ ΡΠ°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°. ΠΠ°ΡΠΈΡΠ΅ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ Π΄Π°Π½Π½ΠΈ ΡΠ΅ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Ρ ΠΏΠΎ ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ° ΠΏΠΎ-Π΄ΠΎΠ»Ρ. ΠΠ° Π±Π°Π·Π°ΡΠ° Π½Π° ΡΠΎΠ·ΠΈ ΡΠΎΡΠΌΠ°Ρ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°ΠΌΠ΅ Π΄Π°Π½Π½ΠΈ ΡΠ΅Π΄ ΠΏΠΎ ΡΠ΅Π΄, Π·Π° Π΄Π° ΡΠΈΠΌΡΠ»ΠΈΡΠ°ΠΌΠ΅ Π΄Π°Π½Π½ΠΈ Π² ΡΠ΅Π°Π»Π½ΠΎ Π²ΡΠ΅ΠΌΠ΅. Π’Π΅Π·ΠΈ ΠΆΡΡΠ½Π°Π»ΠΈ Π½ΠΈ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΊΠ°ΡΠΎ Π΄Π°ΡΠ°, ΡΠΈΠΏ Π·Π°ΠΏΠΈΡΠ²Π°Π½Π΅, ΠΎΡΠ³ΠΎΠ²ΠΎΡ ΠΎΡ ΡΡΡΠ²ΡΡΠ°, IP Π°Π΄ΡΠ΅Ρ ΠΈ Ρ.Π½.
192.52.197.161 - - [30/Apr/2019:21:11:42] "PUT /tag/category/tag HTTP/1.1" [401] 155 "https://harris-lopez.com/categories/about/" "Mozilla/5.0 (Macintosh; PPC Mac OS X 10_11_2) AppleWebKit/5312 (KHTML, like Gecko) Chrome/34.0.855.0 Safari/5312"
ΠΠ° Π±Π°Π·Π°ΡΠ° Π½Π° Π³ΠΎΡΠ½ΠΈΡ ΡΠ΅Π΄ ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° LINE, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ 7 ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π² ΡΠΈΠ³ΡΡΠ½ΠΈ ΡΠΊΠΎΠ±ΠΈ ΠΏΠΎ-Π΄ΠΎΠ»Ρ. Π‘ΡΡΠΎ ΡΠ°ΠΊΠ° ΡΠ΅ Π³ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΊΠ°ΡΠΎ ΠΈΠΌΠ΅Π½Π° Π½Π° ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π² Π½Π°ΡΠ°ΡΠ° ΡΠ°Π±Π»ΠΈΡΠ° ΠΏΠΎ-ΠΊΡΡΠ½ΠΎ.
"""
{remote_addr} - - [{time_local}] "{request_type} {request_path} HTTP/1.1" [{status}] {body_bytes_sent} "{http_referer}" "{http_user_agent}"
"""
ΠΠΊΠΎ ΠΈΠ·Π²ΡΡΡΠ²Π°Ρ ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠ½Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ°, ΠΊΠΎΠ΄ΡΡ ΡΠ΅ΡΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡΡ ΠΎΠ΄Π΅Π½, ΠΌΠ°ΠΊΠ°Ρ Π΄Π° ΡΡΡΠ±Π²Π°ΡΠ΅ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ Π½Π°Π±ΠΎΡ ΠΎΡ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π² ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ Π²ΡΠ΅ΠΌΠ΅Π²ΠΈ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½. ΠΠ° Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Faker, ΠΏΡΠΎΡΡΠΎ ΡΡΠ·Π΄Π°Π²Π°ΠΌΠ΅ ΠΎΠ±Π΅ΠΊΡ ΠΈ ΠΈΠ·Π²ΠΈΠΊΠ²Π°ΠΌΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈΡΠ΅ Π½ΠΈ ΠΌΠ΅ΡΠΎΠ΄ΠΈ. Π ΡΠ°ΡΡΠ½ΠΎΡΡ, Faker Π΅ Π±ΠΈΠ» ΠΏΠΎΠ»Π΅Π·Π΅Π½ Π·Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½Π΅ Π½Π° IP Π°Π΄ΡΠ΅ΡΠΈ, Π° ΡΡΡΠΎ ΠΈ ΡΠ΅Π±ΡΠ°ΠΉΡΠΎΠ²Π΅. ΠΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ΠΈ:
ΡΠ°Π»ΡΠΈΠ²ΠΎ.ipv4()
ΡΠ°Π»ΡΠΈΠ²ΠΎ.uri_path()
ΡΠ°Π»ΡΠΈΠ²ΠΎ.uri()
ΡΠ°Π»ΡΠΈΠ²ΠΎ.user_agent()
from faker import Faker
import time
import random
import os
import numpy as np
from datetime import datetime, timedelta
LINE = """
{remote_addr} - - [{time_local}] "{request_type} {request_path} HTTP/1.1" [{status}] {body_bytes_sent} "{http_referer}" "{http_user_agent}"
"""
def generate_log_line():
fake = Faker()
now = datetime.now()
remote_addr = fake.ipv4()
time_local = now.strftime('%d/%b/%Y:%H:%M:%S')
request_type = random.choice(["GET", "POST", "PUT"])
request_path = "\/" + fake.uri_path()
status = np.random.choice([200, 401, 404], p = [0.9, 0.05, 0.05])
body_bytes_sent = random.choice(range(5, 1000, 1))
http_referer = fake.uri()
http_user_agent = fake.user_agent()
log_line = LINE.format(
remote_addr=remote_addr,
time_local=time_local,
request_type=request_type,
request_path=request_path,
status=status,
body_bytes_sent=body_bytes_sent,
http_referer=http_referer,
http_user_agent=http_user_agent
)
return log_lineΠΡΠ°ΠΉ Π½Π° ΠΏΡΡΠ²Π° ΡΠ°ΡΡ.
Π ΡΠ»Π΅Π΄Π²Π°ΡΠΈΡΠ΅ Π΄Π½ΠΈ ΡΠ΅ ΡΠΏΠΎΠ΄Π΅Π»ΠΈΠΌ Ρ Π²Π°Ρ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° ΡΡΠ°ΡΠΈΡΡΠ°, Π° Π² ΠΌΠΎΠΌΠ΅Π½ΡΠ° ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΠΎ ΠΎΡΠ°ΠΊΠ²Π°ΠΌΠ΅ Π²Π°ΡΠΈΡΠ΅ ΠΊΠΎΠΌΠ΅Π½ΡΠ°ΡΠΈ ;-).
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: habr.com
