ΠΠ΄ΡΠ°Π²Π΅ΠΉΡΠ΅! ΠΠΈΠ΅ ΠΎΠ±ΡΡΠ°Π²Π°ΠΌΠ΅ Ρ ΠΎΡΠ° Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ Π³ΠΎΠ»Π΅ΠΌΠΈ Π΄Π°Π½Π½ΠΈ. ΠΠ΅Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ Π΅ Π΄Π° ΡΠΈ ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΠ΅Π»Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° Π³ΠΎΠ»Π΅ΠΌΠΈ Π΄Π°Π½Π½ΠΈ Π±Π΅Π· ΡΠΎΠ±ΡΡΠ²Π΅Π½ ΠΊΠ»ΡΡΡΠ΅Ρ, Π²ΡΡΡ Ρ ΠΊΠΎΠΉΡΠΎ Π²ΡΠΈΡΠΊΠΈ ΡΡΠ°ΡΡΠ½ΠΈΡΠΈ ΡΠ°Π±ΠΎΡΡΡ Π·Π°Π΅Π΄Π½ΠΎ. ΠΠΎΡΠ°Π΄ΠΈ ΡΠ°Π·ΠΈ ΠΏΡΠΈΡΠΈΠ½Π° Π½Π°ΡΠ°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π²ΠΈΠ½Π°Π³ΠΈ Ρ ΠΈΠΌΠ° π ΠΠΈΠ΅ ΡΠΌΠ΅ Π°Π½Π³Π°ΠΆΠΈΡΠ°Π½ΠΈ Ρ Π½Π΅ΠΉΠ½Π°ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ, Π½Π°ΡΡΡΠΎΠΉΠΊΠ° ΠΈ Π°Π΄ΠΌΠΈΠ½ΠΈΡΡΡΠΈΡΠ°Π½Π΅, Π° ΠΌΠΎΠΌΡΠ΅ΡΠ°ΡΠ° Π΄ΠΈΡΠ΅ΠΊΡΠ½ΠΎ ΡΡΠ°ΡΡΠΈΡΠ°Ρ MapReduce Π·Π°Π΄Π°Π½ΠΈΡ ΡΠ°ΠΌ ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ Spark.
Π ΡΠ°Π·ΠΈ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΡ ΡΠ΅ Π²ΠΈ ΡΠ°Π·ΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ ΡΠ΅ΡΠΈΡ
ΠΌΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Ρ Π½Π΅ΡΠ°Π²Π½ΠΎΠΌΠ΅ΡΠ½ΠΎΡΠΎ Π·Π°ΡΠ΅ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ°, ΠΊΠ°ΡΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ
ΠΌΠ΅ Π½Π°Ρ ΡΠΎΠ±ΡΡΠ²Π΅Π½ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅Π½ ΡΠΊΠ°Π»Π΅Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΠΎΠ±Π»Π°ΠΊΠ°
ΠΏΡΠΎΠ±Π»Π΅ΠΌ
ΠΠ°ΡΠΈΡΡ ΠΊΠ»ΡΡΡΠ΅Ρ Π½Π΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² ΡΠΈΠΏΠΈΡΠ΅Π½ ΡΠ΅ΠΆΠΈΠΌ. ΠΠ·Ρ Π²ΡΡΠ»ΡΠ½Π΅ΡΠΎ Π΅ ΡΠΈΠ»Π½ΠΎ Π½Π΅ΡΠ°Π²Π½ΠΎΠΌΠ΅ΡΠ½ΠΎ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΈΠΌΠ° ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π·Π°Π½ΡΡΠΈΡ, ΠΊΠΎΠ³Π°ΡΠΎ Π²ΡΠΈΡΠΊΠΈΡΠ΅ 30 Π΄ΡΡΠΈ ΠΈ Π΅Π΄ΠΈΠ½ ΡΡΠΈΡΠ΅Π» ΠΎΡΠΈΠ²Π°Ρ Π² ΠΊΠ»ΡΡΡΠ΅ΡΠ° ΠΈ Π·Π°ΠΏΠΎΡΠ²Π°Ρ Π΄Π° Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ. ΠΠ»ΠΈ ΠΏΠ°ΠΊ ΠΈΠΌΠ° Π΄Π½ΠΈ ΠΏΡΠ΅Π΄ΠΈ ΠΊΡΠ°ΠΉΠ½ΠΈΡ ΡΡΠΎΠΊ, ΠΊΠΎΠ³Π°ΡΠΎ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½Π΅ΡΠΎ ΡΠ΅ ΡΠ²Π΅Π»ΠΈΡΠ°Π²Π° ΠΌΠ½ΠΎΠ³ΠΎ. ΠΡΠ΅Π· ΠΎΡΡΠ°Π½Π°Π»ΠΎΡΠΎ Π²ΡΠ΅ΠΌΠ΅ ΠΊΠ»ΡΡΡΠ΅ΡΡΡ ΡΠ°Π±ΠΎΡΠΈ Π² ΡΠ΅ΠΆΠΈΠΌ Π½Π° Π½Π΅Π΄ΠΎΡΠΎΠ²Π°ΡΠ²Π°Π½Π΅.
Π Π΅ΡΠ΅Π½ΠΈΠ΅ β1 Π΅ Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΡΠ΅ ΠΊΠ»ΡΡΡΠ΅Ρ, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΠΈΠ·Π΄ΡΡΠΆΠΈ Π½Π° ΠΏΠΈΠΊΠΎΠ²ΠΈΡΠ΅ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½ΠΈΡ, Π½ΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ Π±Π΅Π·Π΄Π΅ΠΉΡΡΠ²Π°Ρ ΠΏΡΠ΅Π· ΠΎΡΡΠ°Π½Π°Π»ΠΎΡΠΎ Π²ΡΠ΅ΠΌΠ΅.
Π Π΅ΡΠ΅Π½ΠΈΠ΅ β2 Π΅ Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΡΠ΅ ΠΌΠ°Π»ΡΠΊ ΠΊΠ»ΡΡΡΠ΅Ρ, ΠΊΡΠΌ ΠΊΠΎΠΉΡΠΎ ΡΡΡΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ Π²ΡΠ·Π»ΠΈ ΠΏΡΠ΅Π΄ΠΈ ΠΊΠ»Π°ΡΠΎΠ²Π΅ ΠΈ ΠΏΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° ΠΏΠΈΠΊΠΎΠ²ΠΈ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½ΠΈΡ.
Π Π΅ΡΠ΅Π½ΠΈΠ΅ #3 Π΅ Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΡΠ΅ ΠΌΠ°Π»ΡΠΊ ΠΊΠ»ΡΡΡΠ΅Ρ ΠΈ Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅Π½ ΡΠΊΠ°Π»Π΅Ρ, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΡΠ»Π΅Π΄ΠΈ ΡΠ΅ΠΊΡΡΠΎΡΠΎ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ° ΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ API, Π΄ΠΎΠ±Π°Π²Ρ ΠΈ ΠΏΡΠ΅ΠΌΠ°Ρ Π²Π° Π²ΡΠ·Π»ΠΈ ΠΎΡ ΠΊΠ»ΡΡΡΠ΅ΡΠ°.
Π ΡΠ°Π·ΠΈ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΡ ΡΠ΅ Π³ΠΎΠ²ΠΎΡΠΈΠΌ Π·Π° ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ β3. Π’ΠΎΠ·ΠΈ Π°Π²ΡΠΎΡΠΊΠ°Π»Π΅Ρ Π΅ ΡΠΈΠ»Π½ΠΎ Π·Π°Π²ΠΈΡΠΈΠΌ ΠΎΡ Π²ΡΠ½ΡΠ½ΠΈ ΡΠ°ΠΊΡΠΎΡΠΈ, Π° Π½Π΅ ΠΎΡ Π²ΡΡΡΠ΅ΡΠ½ΠΈ, ΠΈ Π΄ΠΎΡΡΠ°Π²ΡΠΈΡΠΈΡΠ΅ ΡΠ΅ΡΡΠΎ Π½Π΅ Π³ΠΎ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΡΡ. ΠΠΈΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΎΠ±Π»Π°ΡΠ½Π°ΡΠ° ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΠ° Π½Π° Mail.ru Cloud Solutions ΠΈ Π½Π°ΠΏΠΈΡΠ°Ρ ΠΌΠ΅ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅Π½ ΡΠΊΠ°Π»Π΅Ρ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ MCS API. Π ΡΡΠΉ ΠΊΠ°ΡΠΎ Π½ΠΈΠ΅ ΡΡΠΈΠΌ ΠΊΠ°ΠΊ Π΄Π° ΡΠ°Π±ΠΎΡΠΈΠΌ Ρ Π΄Π°Π½Π½ΠΈ, ΡΠ΅ΡΠΈΡ ΠΌΠ΅ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ ΠΏΠΎΠ΄ΠΎΠ±Π΅Π½ Π°Π²ΡΠΎΡΠΊΠ°Π»Π΅Ρ Π·Π° Π²Π°ΡΠΈΡΠ΅ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΡΠ΅Π»ΠΈ ΠΈ Π΄Π° Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ Ρ Π²Π°ΡΠΈΡ ΠΎΠ±Π»Π°ΠΊ
ΠΡΠ΅Π΄ΠΏΠΎΡΡΠ°Π²ΠΊΠΈ
ΠΡΡΠ²ΠΎ, ΡΡΡΠ±Π²Π° Π΄Π° ΠΈΠΌΠ°ΡΠ΅ Hadoop ΠΊΠ»ΡΡΡΠ΅Ρ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΡΠΎ Π½Π° HDP.
ΠΠ° Π΄Π° ΠΌΠΎΠ³Π°Ρ Π²Π°ΡΠΈΡΠ΅ Π²ΡΠ·Π»ΠΈ Π΄Π° Π±ΡΠ΄Π°Ρ Π±ΡΡΠ·ΠΎ Π΄ΠΎΠ±Π°Π²ΡΠ½ΠΈ ΠΈ ΠΏΡΠ΅ΠΌΠ°Ρ Π²Π°Π½ΠΈ, ΡΡΡΠ±Π²Π° Π΄Π° ΠΈΠΌΠ°ΡΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΎ ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π½Π° ΡΠΎΠ»ΠΈΡΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ Π²ΡΠ·Π»ΠΈΡΠ΅.
- ΠΠ»Π°Π²Π΅Π½ Π²ΡΠ·Π΅Π». Π, Π½ΡΠΌΠ° Π½ΡΠΆΠ΄Π° Π΄Π° ΠΎΠ±ΡΡΠ½ΡΠ²Π°ΡΠ΅ Π½ΠΈΡΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ: ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡΡ Π²ΡΠ·Π΅Π» Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ°, Π½Π° ΠΊΠΎΠΉΡΠΎ Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ΅ ΡΡΠ°ΡΡΠΈΡΠ° Π΄ΡΠ°ΠΉΠ²Π΅ΡΡΡ Π½Π° Spark, Π°ΠΊΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΠΈΡ ΡΠ΅ΠΆΠΈΠΌ.
- ΠΡΠ·Π΅Π» Π·Π° Π΄Π°ΡΠ°. Π’ΠΎΠ²Π° Π΅ Π²ΡΠ·Π΅Π»ΡΡ, Π½Π° ΠΊΠΎΠΉΡΠΎ ΡΡΡ ΡΠ°Π½ΡΠ²Π°ΡΠ΅ Π΄Π°Π½Π½ΠΈ Π·Π° HDFS ΠΈ ΠΊΡΠ΄Π΅ΡΠΎ ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π°Ρ ΠΈΠ·ΡΠΈΡΠ»Π΅Π½ΠΈΡΡΠ°.
- ΠΠ·ΡΠΈΡΠ»ΠΈΡΠ΅Π»Π΅Π½ Π²ΡΠ·Π΅Π». Π’ΠΎΠ²Π° Π΅ Π²ΡΠ·Π΅Π», ΠΊΡΠ΄Π΅ΡΠΎ Π½Π΅ ΡΡΡ ΡΠ°Π½ΡΠ²Π°ΡΠ΅ Π½ΠΈΡΠΎ Π² HDFS, Π½ΠΎ ΠΊΡΠ΄Π΅ΡΠΎ ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π°Ρ ΠΈΠ·ΡΠΈΡΠ»Π΅Π½ΠΈΡ.
ΠΠ°ΠΆΠ΅Π½ ΠΌΠΎΠΌΠ΅Π½Ρ. ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎΡΠΎ ΠΌΠ°ΡΠ°Π±ΠΈΡΠ°Π½Π΅ ΡΠ΅ ΡΠ΅ ΡΠ»ΡΡΠΈ ΠΏΠΎΡΠ°Π΄ΠΈ Π²ΡΠ·Π»ΠΈ ΠΎΡ ΡΡΠ΅ΡΠΈ ΡΠΈΠΏ. ΠΠΊΠΎ Π·Π°ΠΏΠΎΡΠ½Π΅ΡΠ΅ Π΄Π° ΠΏΡΠΈΠ΅ΠΌΠ°ΡΠ΅ ΠΈ Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ Π²ΡΠ·Π»ΠΈ ΠΎΡ Π²ΡΠΎΡΠΈΡ ΡΠΈΠΏ, ΡΠΊΠΎΡΠΎΡΡΡΠ° Π½Π° ΡΠ΅Π°ΠΊΡΠΈΡ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Π½ΠΈΡΠΊΠ° - ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ΡΠΎ ΠΎΡ Π΅ΠΊΡΠΏΠ»ΠΎΠ°ΡΠ°ΡΠΈΡ ΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΡΠΎ ΠΏΠΎΠ΄Π°Π²Π°Π½Π΅ ΡΠ΅ ΠΎΡΠ½Π΅ΠΌΠ΅ ΡΠ°ΡΠΎΠ²Π΅ Π½Π° Π²Π°ΡΠΈΡ ΠΊΠ»ΡΡΡΠ΅Ρ. Π’ΠΎΠ²Π°, ΡΠ°Π·Π±ΠΈΡΠ° ΡΠ΅, Π½Π΅ Π΅ ΡΠΎΠ²Π°, ΠΊΠΎΠ΅ΡΠΎ ΠΎΡΠ°ΠΊΠ²Π°ΡΠ΅ ΠΎΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎΡΠΎ ΠΌΠ°ΡΠ°Π±ΠΈΡΠ°Π½Π΅. Π’ΠΎΠ΅ΡΡ Π½Π΅ Π΄ΠΎΠΊΠΎΡΠ²Π°ΠΌΠ΅ Π²ΡΠ·Π»ΠΈ ΠΎΡ ΠΏΡΡΠ²ΠΈ ΠΈ Π²ΡΠΎΡΠΈ ΡΠΈΠΏ. Π’Π΅ ΡΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ²Π°Ρ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½ ΠΆΠΈΠ·Π½Π΅ΡΠΏΠΎΡΠΎΠ±Π΅Π½ ΠΊΠ»ΡΡΡΠ΅Ρ, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π° ΠΏΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠΈΡΠ΅Π»Π½ΠΎΡΡΡΠ° Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°.
Π ΡΠ°ΠΊΠ°, Π½Π°ΡΠΈΡΡ autoscaler Π΅ Π½Π°ΠΏΠΈΡΠ°Π½ Π½Π° Python 3, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Ambari API Π·Π° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ½ΠΈ ΡΡΠ»ΡΠ³ΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°
ΠΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ° Π½Π° ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΡΠΎ
- ΠΠΎΠ΄ΡΠ»
autoscaler.py
. Π‘ΡΠ΄ΡΡΠΆΠ° ΡΡΠΈ ΠΊΠ»Π°ΡΠ°: 1) ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ Ambari, 2) ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ MCS, 3) ΡΡΠ½ΠΊΡΠΈΠΈ, ΡΠ²ΡΡΠ·Π°Π½ΠΈ ΠΏΡΡΠΊΠΎ Ρ Π»ΠΎΠ³ΠΈΠΊΠ°ΡΠ° Π½Π° autoscaler. - Π‘ΠΊΡΠΈΠΏΡ
observer.py
. ΠΠΎ ΡΡΡΠ΅ΡΡΠ²ΠΎ ΡΠ΅ ΡΡΡΡΠΎΠΈ ΠΎΡ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΏΡΠ°Π²ΠΈΠ»Π°: ΠΊΠΎΠ³Π° ΠΈ Π² ΠΊΠ°ΠΊΠ²ΠΈ ΠΌΠΎΠΌΠ΅Π½ΡΠΈ Π΄Π° ΡΠ΅ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ ΡΡΠ½ΠΊΡΠΈΠΈΡΠ΅ Π·Π° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎ ΠΌΠ°ΡΠ°Π±ΠΈΡΠ°Π½Π΅. - ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π΅Π½ ΡΠ°ΠΉΠ»
config.py
. Π’ΠΎΠΉ ΡΡΠ΄ΡΡΠΆΠ° Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΡΠΏΠΈΡΡΠΊ Ρ Π²ΡΠ·Π»ΠΈ, ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈ Π·Π° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎ ΠΌΠ°ΡΠ°Π±ΠΈΡΠ°Π½Π΅ ΠΈ Π΄ΡΡΠ³ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ, ΠΊΠΎΠΈΡΠΎ Π²Π»ΠΈΡΡΡ Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π½Π° ΡΠΎΠ²Π° ΠΊΠΎΠ»ΠΊΠΎ Π²ΡΠ΅ΠΌΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·ΡΠ°ΠΊΠ° ΠΎΡ ΠΌΠΎΠΌΠ΅Π½ΡΠ°, Π² ΠΊΠΎΠΉΡΠΎ Π΅ Π΄ΠΎΠ±Π°Π²Π΅Π½ Π½ΠΎΠ² Π²ΡΠ·Π΅Π». ΠΠΌΠ° ΠΈ Π²ΡΠ΅ΠΌΠ΅Π²ΠΈ ΠΎΡΠΌΠ΅ΡΠΊΠΈ Π·Π° Π½Π°ΡΠ°Π»ΠΎΡΠΎ Π½Π° ΠΊΠ»Π°ΡΠΎΠ²Π΅ΡΠ΅, ΡΠ°ΠΊΠ° ΡΠ΅ ΠΏΡΠ΅Π΄ΠΈ ΠΊΠ»Π°ΡΠ° Π΄Π° ΡΠ΅ ΡΡΠ°ΡΡΠΈΡΠ° ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»Π½ΠΎ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½Π°ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ°.
ΠΠ΅ΠΊΠ° ΡΠ΅Π³Π° Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠ°ΡΡΠ΅ΡΠ°ΡΠ° ΠΊΠΎΠ΄ Π² ΠΏΡΡΠ²ΠΈΡΠ΅ Π΄Π²Π° ΡΠ°ΠΉΠ»Π°.
1. ΠΠΎΠ΄ΡΠ» Autoscaler.py
ΠΠ»Π°Ρ ΠΠΌΠ±Π°ΡΠΈ
ΠΡΠΎ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠ°ΡΡΠ΅ ΠΊΠΎΠ΄, ΡΡΠ΄ΡΡΠΆΠ°Ρ ΠΊΠ»Π°Ρ Ambari
:
class Ambari:
def __init__(self, ambari_url, cluster_name, headers, auth):
self.ambari_url = ambari_url
self.cluster_name = cluster_name
self.headers = headers
self.auth = auth
def stop_all_services(self, hostname):
url = self.ambari_url + self.cluster_name + '/hosts/' + hostname + '/host_components/'
url2 = self.ambari_url + self.cluster_name + '/hosts/' + hostname
req0 = requests.get(url2, headers=self.headers, auth=self.auth)
services = req0.json()['host_components']
services_list = list(map(lambda x: x['HostRoles']['component_name'], services))
data = {
"RequestInfo": {
"context":"Stop All Host Components",
"operation_level": {
"level":"HOST",
"cluster_name": self.cluster_name,
"host_names": hostname
},
"query":"HostRoles/component_name.in({0})".format(",".join(services_list))
},
"Body": {
"HostRoles": {
"state":"INSTALLED"
}
}
}
req = requests.put(url, data=json.dumps(data), headers=self.headers, auth=self.auth)
if req.status_code in [200, 201, 202]:
message = 'Request accepted'
else:
message = req.status_code
return message
ΠΠΎ-Π³ΠΎΡΠ΅, ΠΊΠ°ΡΠΎ ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ΡΠΎ Π½Π° ΡΡΠ½ΠΊΡΠΈΡΡΠ° stop_all_services
, ΠΊΠΎΠ΅ΡΠΎ ΡΠΏΠΈΡΠ° Π²ΡΠΈΡΠΊΠΈ ΡΡΠ»ΡΠ³ΠΈ Π½Π° ΠΆΠ΅Π»Π°Π½ΠΈΡ ΠΊΠ»ΡΡΡΠ΅ΡΠ΅Π½ Π²ΡΠ·Π΅Π».
ΠΠ° Π²Ρ
ΠΎΠ΄Π° Π½Π° ΠΊΠ»Π°ΡΠ° Ambari
ΠΏΡΠ΅ΠΌΠΈΠ½Π°Π²Π°Ρ:
ambari_url
, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΊΠ°ΡΠΎ'http://localhost:8080/api/v1/clusters/'
,cluster_name
β ΠΈΠΌΠ΅ΡΠΎ Π½Π° Π²Π°ΡΠΈΡ ΠΊΠ»ΡΡΡΠ΅Ρ Π² Ambari,headers = {'X-Requested-By': 'ambari'}
- ΠΈ Π²ΡΡΡΠ΅
auth
Π΅ΡΠΎ Π²Π°ΡΠ΅ΡΠΎ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎ ΠΈΠΌΠ΅ ΠΈ ΠΏΠ°ΡΠΎΠ»Π° Π·Π° Ambari:auth = ('login', 'password')
.
Π‘Π°ΠΌΠ°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π½Π΅ Π΅ Π½ΠΈΡΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΎΡ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½ΠΈΡ ΠΏΡΠ΅Π· REST API ΠΊΡΠΌ Ambari. ΠΡ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠ° Π³Π»Π΅Π΄Π½Π° ΡΠΎΡΠΊΠ° ΠΏΡΡΠ²ΠΎ ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΡΠΏΠΈΡΡΠΊ Ρ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°Π½ΠΈ ΡΡΠ»ΡΠ³ΠΈ Π½Π° Π²ΡΠ·Π΅Π» ΠΈ ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° ΠΈΡΠΊΠ°ΠΌΠ΅ ΠΎΡ Π΄Π°Π΄Π΅Π½ ΠΊΠ»ΡΡΡΠ΅Ρ, ΠΎΡ Π΄Π°Π΄Π΅Π½ Π²ΡΠ·Π΅Π», Π΄Π° ΠΏΡΠ΅Ρ
Π²ΡΡΠ»ΠΈΠΌ ΡΡΠ»ΡΠ³ΠΈ ΠΎΡ ΡΠΏΠΈΡΡΠΊΠ° ΠΊΡΠΌ ΡΡΡΡΠΎΡΠ½ΠΈΠ΅ΡΠΎ INSTALLED
. Π€ΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° Π²ΡΠΈΡΠΊΠΈ ΡΡΠ»ΡΠ³ΠΈ, Π·Π° ΠΏΡΠ΅Ρ
Π²ΡΡΠ»ΡΠ½Π΅ Π½Π° Π²ΡΠ·Π»ΠΈ Π² ΡΡΡΡΠΎΡΠ½ΠΈΠ΅ Maintenance
ΠΈ Ρ.Π½. ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Ρ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΈ - ΡΠ΅ ΡΠ° ΡΠ°ΠΌΠΎ Π½ΡΠΊΠΎΠ»ΠΊΠΎ Π·Π°ΡΠ²ΠΊΠΈ ΠΏΡΠ΅Π· API.
ΠΠ»Π°Ρ Mcs
ΠΡΠΎ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠ°ΡΡΠ΅ ΠΊΠΎΠ΄, ΡΡΠ΄ΡΡΠΆΠ°Ρ ΠΊΠ»Π°Ρ Mcs
:
class Mcs:
def __init__(self, id1, id2, password):
self.id1 = id1
self.id2 = id2
self.password = password
self.mcs_host = 'https://infra.mail.ru:8774/v2.1'
def vm_turn_on(self, hostname):
self.token = self.get_mcs_token()
host = self.hostname_to_vmname(hostname)
vm_id = self.get_vm_id(host)
mcs_url1 = self.mcs_host + '/servers/' + self.vm_id + '/action'
headers = {
'X-Auth-Token': '{0}'.format(self.token),
'Content-Type': 'application/json'
}
data = {'os-start' : 'null'}
mcs = requests.post(mcs_url1, data=json.dumps(data), headers=headers)
return mcs.status_code
ΠΠ° Π²Ρ
ΠΎΠ΄Π° Π½Π° ΠΊΠ»Π°ΡΠ° Mcs
ΠΏΡΠ΅Π΄Π°Π²Π°ΠΌΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° Π½Π° ΠΏΡΠΎΠ΅ΠΊΡΠ° Π² ΠΎΠ±Π»Π°ΠΊΠ° ΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ, ΠΊΠ°ΠΊΡΠΎ ΠΈ Π½Π΅Π³ΠΎΠ²Π°ΡΠ° ΠΏΠ°ΡΠΎΠ»Π°. ΠΡΠ² ΡΡΠ½ΠΊΡΠΈΡ vm_turn_on
ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° Π²ΠΊΠ»ΡΡΠΈΠΌ Π΅Π΄Π½Π° ΠΎΡ ΠΌΠ°ΡΠΈΠ½ΠΈΡΠ΅. ΠΠΎΠ³ΠΈΠΊΠ°ΡΠ° ΡΡΠΊ Π΅ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-ΡΠ»ΠΎΠΆΠ½Π°. Π Π½Π°ΡΠ°Π»ΠΎΡΠΎ Π½Π° ΠΊΠΎΠ΄Π° ΡΠ΅ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ ΡΡΠΈ Π΄ΡΡΠ³ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ: 1) ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΠΎΠΊΠ΅Π½, 2) ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ²Π°ΠΌΠ΅ ΠΈΠΌΠ΅ΡΠΎ Π½Π° Ρ
ΠΎΡΡΠ° Π² ΠΈΠΌΠ΅ΡΠΎ Π½Π° ΠΌΠ°ΡΠΈΠ½Π°ΡΠ° Π² MCS, 3) Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° Π½Π° ΡΠ°Π·ΠΈ ΠΌΠ°ΡΠΈΠ½Π°. Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΠΏΡΠΎΡΡΠΎ ΠΏΡΠ°Π²ΠΈΠΌ Π·Π°ΡΠ²ΠΊΠ° Π·Π° ΠΏΡΠ±Π»ΠΈΠΊΡΠ²Π°Π½Π΅ ΠΈ ΡΡΠ°ΡΡΠΈΡΠ°ΠΌΠ΅ ΡΠ°Π·ΠΈ ΠΌΠ°ΡΠΈΠ½Π°.
ΠΡΠΎ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΡΡΠ½ΠΊΡΠΈΡΡΠ° Π·Π° ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ Π½Π° ΡΠΎΠΊΠ΅Π½:
def get_mcs_token(self):
url = 'https://infra.mail.ru:35357/v3/auth/tokens?nocatalog'
headers = {'Content-Type': 'application/json'}
data = {
'auth': {
'identity': {
'methods': ['password'],
'password': {
'user': {
'id': self.id1,
'password': self.password
}
}
},
'scope': {
'project': {
'id': self.id2
}
}
}
}
params = (('nocatalog', ''),)
req = requests.post(url, data=json.dumps(data), headers=headers, params=params)
self.token = req.headers['X-Subject-Token']
return self.token
ΠΠ»Π°Ρ Π½Π° Autoscaler
Π’ΠΎΠ·ΠΈ ΠΊΠ»Π°Ρ ΡΡΠ΄ΡΡΠΆΠ° ΡΡΠ½ΠΊΡΠΈΠΈ, ΡΠ²ΡΡΠ·Π°Π½ΠΈ ΡΡΡ ΡΠ°ΠΌΠ°ΡΠ° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ°.
ΠΡΠΎ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΡΠ°ΡΡ ΠΎΡ ΠΊΠΎΠ΄Π° Π·Π° ΡΠΎΠ·ΠΈ ΠΊΠ»Π°Ρ:
class Autoscaler:
def __init__(self, ambari, mcs, scaling_hosts, yarn_ram_per_node, yarn_cpu_per_node):
self.scaling_hosts = scaling_hosts
self.ambari = ambari
self.mcs = mcs
self.q_ram = deque()
self.q_cpu = deque()
self.num = 0
self.yarn_ram_per_node = yarn_ram_per_node
self.yarn_cpu_per_node = yarn_cpu_per_node
def scale_down(self, hostname):
flag1 = flag2 = flag3 = flag4 = flag5 = False
if hostname in self.scaling_hosts:
while True:
time.sleep(5)
status1 = self.ambari.decommission_nodemanager(hostname)
if status1 == 'Request accepted' or status1 == 500:
flag1 = True
logging.info('Decomission request accepted: {0}'.format(flag1))
break
while True:
time.sleep(5)
status3 = self.ambari.check_service(hostname, 'NODEMANAGER')
if status3 == 'INSTALLED':
flag3 = True
logging.info('Nodemaneger decommissioned: {0}'.format(flag3))
break
while True:
time.sleep(5)
status2 = self.ambari.maintenance_on(hostname)
if status2 == 'Request accepted' or status2 == 500:
flag2 = True
logging.info('Maintenance request accepted: {0}'.format(flag2))
break
while True:
time.sleep(5)
status4 = self.ambari.check_maintenance(hostname, 'NODEMANAGER')
if status4 == 'ON' or status4 == 'IMPLIED_FROM_HOST':
flag4 = True
self.ambari.stop_all_services(hostname)
logging.info('Maintenance is on: {0}'.format(flag4))
logging.info('Stopping services')
break
time.sleep(90)
status5 = self.mcs.vm_turn_off(hostname)
while True:
time.sleep(5)
status5 = self.mcs.get_vm_info(hostname)['server']['status']
if status5 == 'SHUTOFF':
flag5 = True
logging.info('VM is turned off: {0}'.format(flag5))
break
if flag1 and flag2 and flag3 and flag4 and flag5:
message = 'Success'
logging.info('Scale-down finished')
logging.info('Cooldown period has started. Wait for several minutes')
return message
ΠΡΠΈΠ΅ΠΌΠ°ΠΌΠ΅ ΠΊΠ»Π°ΡΠΎΠ²Π΅ Π·Π° Π²Π»ΠΈΠ·Π°Π½Π΅. Ambari
ΠΈ Mcs
, ΡΠΏΠΈΡΡΠΊ Ρ Π²ΡΠ·Π»ΠΈ, ΠΊΠΎΠΈΡΠΎ ΡΠ° ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈ Π·Π° ΠΌΠ°ΡΠ°Π±ΠΈΡΠ°Π½Π΅, ΠΊΠ°ΠΊΡΠΎ ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½Π΅ Π½Π° Π²ΡΠ·Π΅Π»: ΠΏΠ°ΠΌΠ΅Ρ ΠΈ ΠΏΡΠΎΡΠ΅ΡΠΎΡ, ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ Π·Π° Π²ΡΠ·Π΅Π»Π° Π² YARN. ΠΠΌΠ° ΠΈ 2 Π²ΡΡΡΠ΅ΡΠ½ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡΠ° q_ram, q_cpu, ΠΊΠΎΠΈΡΠΎ ΡΠ° ΠΎΠΏΠ°ΡΠΊΠΈ. ΠΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ Π³ΠΈ, Π½ΠΈΠ΅ ΡΡΡ
ΡΠ°Π½ΡΠ²Π°ΠΌΠ΅ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈΡΠ΅ Π½Π° ΡΠ΅ΠΊΡΡΠΎΡΠΎ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ°. ΠΠΊΠΎ Π²ΠΈΠ΄ΠΈΠΌ, ΡΠ΅ ΠΏΡΠ΅Π· ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ 5 ΠΌΠΈΠ½ΡΡΠΈ Π΅ ΠΈΠΌΠ°Π»ΠΎ ΠΏΠΎΡΡΠΎΡΠ½Π½ΠΎ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΎ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½Π΅, ΡΠΎΠ³Π°Π²Π° ΡΠ΅ΡΠ°Π²Π°ΠΌΠ΅, ΡΠ΅ ΡΡΡΠ±Π²Π° Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ +1 Π²ΡΠ·Π΅Π» ΠΊΡΠΌ ΠΊΠ»ΡΡΡΠ΅ΡΠ°. Π‘ΡΡΠΎΡΠΎ Π²Π°ΠΆΠΈ ΠΈ Π·Π° ΡΡΡΡΠΎΡΠ½ΠΈΠ΅ΡΠΎ Π½Π° Π½Π΅Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ°.
ΠΠΎΠ΄ΡΡ ΠΏΠΎ-Π³ΠΎΡΠ΅ Π΅ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΡΠΎ ΠΏΡΠ΅ΠΌΠ°Ρ
Π²Π° ΠΌΠ°ΡΠΈΠ½Π° ΠΎΡ ΠΊΠ»ΡΡΡΠ΅ΡΠ° ΠΈ Ρ ΡΠΏΠΈΡΠ° Π² ΠΎΠ±Π»Π°ΠΊΠ°. ΠΡΡΠ²ΠΎ ΠΈΠΌΠ° ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ ΠΎΡ Π΅ΠΊΡΠΏΠ»ΠΎΠ°ΡΠ°ΡΠΈΡ YARN Nodemanager
, ΡΠ»Π΅Π΄ ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ΠΆΠΈΠΌΡΡ ΡΠ΅ Π²ΠΊΠ»ΡΡΠ²Π° Maintenance
, ΡΠ»Π΅Π΄ ΠΊΠΎΠ΅ΡΠΎ ΡΠΏΠΈΡΠ°ΠΌΠ΅ Π²ΡΠΈΡΠΊΠΈ ΡΡΠ»ΡΠ³ΠΈ Π½Π° ΠΌΠ°ΡΠΈΠ½Π°ΡΠ° ΠΈ ΠΈΠ·ΠΊΠ»ΡΡΠ²Π°ΠΌΠ΅ Π²ΠΈΡΡΡΠ°Π»Π½Π°ΡΠ° ΠΌΠ°ΡΠΈΠ½Π° Π² ΠΎΠ±Π»Π°ΠΊΠ°.
2. Π‘ΠΊΡΠΈΠΏΡ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π».py
ΠΡΠΈΠΌΠ΅ΡΠ΅Π½ ΠΊΠΎΠ΄ ΠΎΡ ΡΠ°ΠΌ:
if scaler.assert_up(config.scale_up_thresholds) == True:
hostname = cloud.get_vm_to_up(config.scaling_hosts)
if hostname != None:
status1 = scaler.scale_up(hostname)
if status1 == 'Success':
text = {"text": "{0} has been successfully scaled-up".format(hostname)}
post = {"text": "{0}".format(text)}
json_data = json.dumps(post)
req = requests.post(webhook, data=json_data.encode('ascii'), headers={'Content-Type': 'application/json'})
time.sleep(config.cooldown_period*60)
Π Π½Π΅Π³ΠΎ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ Π΄Π°Π»ΠΈ ΡΠ° ΡΡΠ·Π΄Π°Π΄Π΅Π½ΠΈ ΡΡΠ»ΠΎΠ²ΠΈΡ Π·Π° ΡΠ²Π΅Π»ΠΈΡΠ°Π²Π°Π½Π΅ Π½Π° ΠΊΠ°ΠΏΠ°ΡΠΈΡΠ΅ΡΠ° Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ° ΠΈ Π΄Π°Π»ΠΈ ΠΈΠΌΠ° ΡΠ΅Π·Π΅ΡΠ²Π½ΠΈ ΠΌΠ°ΡΠΈΠ½ΠΈ, ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΠΈΠΌΠ΅ΡΠΎ Π½Π° Ρ
ΠΎΡΡΠ° Π½Π° Π΅Π΄Π½Π° ΠΎΡ ΡΡΡ
, Π΄ΠΎΠ±Π°Π²ΡΠΌΠ΅ Ρ ΠΊΡΠΌ ΠΊΠ»ΡΡΡΠ΅ΡΠ° ΠΈ ΠΏΡΠ±Π»ΠΈΠΊΡΠ²Π°ΠΌΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π·Π° ΡΠΎΠ²Π° Π² Slack Π½Π° Π½Π°ΡΠΈΡ Π΅ΠΊΠΈΠΏ. Π‘Π»Π΅Π΄ ΠΊΠΎΠ΅ΡΠΎ Π·Π°ΠΏΠΎΡΠ²Π° cooldown_period
, ΠΊΠΎΠ³Π°ΡΠΎ Π½Π΅ Π΄ΠΎΠ±Π°Π²ΡΠΌΠ΅ ΠΈΠ»ΠΈ ΠΏΡΠ΅ΠΌΠ°Ρ
Π²Π°ΠΌΠ΅ Π½ΠΈΡΠΎ ΠΎΡ ΠΊΠ»ΡΡΡΠ΅ΡΠ°, Π° ΠΏΡΠΎΡΡΠΎ Π½Π°Π±Π»ΡΠ΄Π°Π²Π°ΠΌΠ΅ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½Π΅ΡΠΎ. ΠΠΊΠΎ ΡΠ΅ Π΅ ΡΡΠ°Π±ΠΈΠ»ΠΈΠ·ΠΈΡΠ°Π» ΠΈ Π΅ Π² ΠΊΠΎΡΠΈΠ΄ΠΎΡΠ° Π½Π° ΠΎΠΏΡΠΈΠΌΠ°Π»Π½ΠΈΡΠ΅ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ Π½Π° Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½Π΅, ΡΠΎΠ³Π°Π²Π° ΠΏΡΠΎΡΡΠΎ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ°Π²Π°ΠΌΠ΅ Π½Π°Π±Π»ΡΠ΄Π΅Π½ΠΈΠ΅ΡΠΎ. ΠΠΊΠΎ Π΅Π΄ΠΈΠ½ Π²ΡΠ·Π΅Π» Π½Π΅ Π΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ΅Π½, ΡΠΎΠ³Π°Π²Π° Π΄ΠΎΠ±Π°Π²ΡΠΌΠ΅ ΠΎΡΠ΅ Π΅Π΄ΠΈΠ½.
ΠΠ° ΡΠ»ΡΡΠ°ΠΈΡΠ΅, ΠΊΠΎΠ³Π°ΡΠΎ Π½ΠΈ ΠΏΡΠ΅Π΄ΡΡΠΎΠΈ ΡΡΠΎΠΊ, Π²Π΅ΡΠ΅ Π·Π½Π°Π΅ΠΌ ΡΡΡ ΡΠΈΠ³ΡΡΠ½ΠΎΡΡ, ΡΠ΅ Π΅Π΄ΠΈΠ½ Π²ΡΠ·Π΅Π» Π½ΡΠΌΠ° Π΄Π° Π΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ΅Π½, ΡΠ°ΠΊΠ° ΡΠ΅ Π²Π΅Π΄Π½Π°Π³Π° ΡΡΠ°ΡΡΠΈΡΠ°ΠΌΠ΅ Π²ΡΠΈΡΠΊΠΈ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΈ Π²ΡΠ·Π»ΠΈ ΠΈ Π³ΠΈ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°ΠΌΠ΅ Π°ΠΊΡΠΈΠ²Π½ΠΈ Π΄ΠΎ ΠΊΡΠ°Ρ Π½Π° ΡΡΠΎΠΊΠ°. Π’ΠΎΠ²Π° ΡΠ΅ ΡΠ»ΡΡΠ²Π° Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΡΠΏΠΈΡΡΠΊ Ρ Π²ΡΠ΅ΠΌΠ΅Π²ΠΈ ΠΊΠ»Π΅ΠΉΠΌΡΠ° Π½Π° Π΄Π΅ΠΉΠ½ΠΎΡΡΡΠ°.
ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
Autoscaler Π΅ Π΄ΠΎΠ±ΡΠΎ ΠΈ ΡΠ΄ΠΎΠ±Π½ΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π·Π° ΡΠ»ΡΡΠ°ΠΈΡΠ΅, ΠΊΠΎΠ³Π°ΡΠΎ ΠΈΠΌΠ°ΡΠ΅ Π½Π΅ΡΠ°Π²Π½ΠΎΠΌΠ΅ΡΠ½ΠΎ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ°. ΠΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΠΏΠΎΡΡΠΈΠ³Π°ΡΠ΅ ΠΆΠ΅Π»Π°Π½Π°ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ° Π·Π° ΠΏΠΈΠΊΠΎΠ²ΠΈ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½ΠΈΡ ΠΈ Π² ΡΡΡΠΎΡΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π΅ Π·Π°Π΄ΡΡΠΆΠ°ΡΠ΅ ΡΠΎΠ·ΠΈ ΠΊΠ»ΡΡΡΠ΅Ρ ΠΏΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° Π½Π΅Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½Π΅, ΡΠΏΠ΅ΡΡΡΠ²Π°ΠΉΠΊΠΈ ΠΏΠ°ΡΠΈ. Π, ΠΎΡΠ²Π΅Π½ ΡΠΎΠ²Π° Π²ΡΠΈΡΠΊΠΎ ΡΠΎΠ²Π° ΡΠ΅ ΡΠ»ΡΡΠ²Π° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎ, Π±Π΅Π· Π²Π°ΡΠ΅ΡΠΎ ΡΡΠ°ΡΡΠΈΠ΅. Π‘Π°ΠΌΠΈΡΡ autoscaler Π½Π΅ Π΅ Π½ΠΈΡΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΎΡ Π½Π°Π±ΠΎΡ ΠΎΡ Π·Π°ΡΠ²ΠΊΠΈ ΠΊΡΠΌ API Π½Π° ΠΌΠ΅Π½ΠΈΠ΄ΠΆΡΡΠ° Π½Π° ΠΊΠ»ΡΡΡΠ΅ΡΠ° ΠΈ API Π½Π° ΠΎΠ±Π»Π°ΡΠ½ΠΈΡ Π΄ΠΎΡΡΠ°Π²ΡΠΈΠΊ, Π½Π°ΠΏΠΈΡΠ°Π½ΠΈ ΡΠΏΠΎΡΠ΅Π΄ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ°. Π’ΠΎΠ²Π°, ΠΊΠΎΠ΅ΡΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡΠ΅, Π΅ ΡΠ°Π·Π΄Π΅Π»ΡΠ½Π΅ΡΠΎ Π½Π° Π²ΡΠ·Π»ΠΈΡΠ΅ Π½Π° 3 Π²ΠΈΠ΄Π°, ΠΊΠ°ΠΊΡΠΎ ΠΏΠΈΡΠ°Ρ ΠΌΠ΅ ΠΏΠΎ-ΡΠ°Π½ΠΎ. Π ΡΠ΅ Π±ΡΠ΄Π΅ΡΠ΅ ΡΠ°ΡΡΠ»ΠΈΠ²ΠΈ.
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com