Apache Bigtop și alegerea unei distribuții Hadoop astăzi

Apache Bigtop și alegerea unei distribuții Hadoop astăzi

Probabil că nu este un secret pentru nimeni că anul trecut a fost un an de mari schimbări pentru Apache Hadoop. Anul trecut, Cloudera și Hortonworks au fuzionat (în esență, achiziția acesteia din urmă), iar Mapr, din cauza unor probleme financiare grave, a fost vândută către Hewlett Packard. Și dacă cu câțiva ani mai devreme, în cazul instalațiilor on-premise, de multe ori trebuia să se facă alegerea între Cloudera și Hortonworks, astăzi, vai, nu avem această alegere. O altă surpriză a fost faptul că Cloudera a anunțat în februarie a acestui an că va înceta lansarea de ansambluri binare ale distribuției sale în depozitul public, iar acestea sunt acum disponibile doar printr-un abonament plătit. Desigur, este încă posibil să descărcați cele mai recente versiuni de CDH și HDP lansate înainte de sfârșitul anului 2019, iar suportul pentru acestea este așteptat timp de unul până la doi ani. Dar ce să faci în continuare? Pentru cei care au plătit anterior un abonament, nimic nu s-a schimbat. Iar pentru cei care nu doresc să treacă la versiunea plătită a distribuției, dar doresc totuși să poată primi cele mai recente versiuni ale componentelor clusterului, precum și patch-uri și alte actualizări, am pregătit acest articol. În ea vom analiza posibile opțiuni pentru a ieși din această situație.

Articolul este mai mult o recenzie. Nu va conține o comparație a distribuțiilor și o analiză detaliată a acestora și nu vor exista rețete pentru instalarea și configurarea acestora. Ce se va intampla? Vom vorbi pe scurt despre o astfel de distribuție precum Arenadata Hadoop, care merită pe bună dreptate atenția noastră datorită disponibilității sale, care este foarte rară astăzi. Și apoi vom vorbi despre Vanilla Hadoop, în principal despre cum poate fi „gătit” folosind Apache Bigtop. Gata? Atunci bun venit la cat.

Arenadata Hadoop

Apache Bigtop și alegerea unei distribuții Hadoop astăzi

Acesta este un kit de distribuție complet nou și, până acum, puțin cunoscut pentru dezvoltare internă. Din păcate, momentan pe Habré există doar acest articol.

Mai multe informații pot fi găsite pe oficial On-line proiect. Cele mai recente versiuni ale distribuției se bazează pe Hadoop 3.1.2 pentru versiunea 3 și 2.8.5 pentru versiunea 2.

Puteți găsi informații despre foaia de parcurs aici.

Apache Bigtop și alegerea unei distribuții Hadoop astăzi
Interfață Arenadata Cluster Manager

Produsul de bază al Arenadata este Arenadata Cluster Manager (ADCM), care este folosit pentru a instala, configura și monitoriza diverse soluții software ale companiei. ADCM este distribuit gratuit, iar funcționalitatea sa este extinsă prin adăugarea de pachete, care sunt un set de ansible-playbooks. Pachetele sunt împărțite în două tipuri: întreprindere și comunitate. Acestea din urmă sunt disponibile pentru descărcare gratuită de pe site-ul Arenadata. De asemenea, este posibil să vă dezvoltați propriul pachet și să îl conectați la ADCM.

Pentru implementarea și gestionarea Hadoop 3, o versiune comunitară a pachetului este oferită împreună cu ADCM, dar pentru Hadoop 2 există doar Apache Ambari Ca o alternativa. În ceea ce privește depozitele cu pachete, acestea sunt deschise accesului public, pot fi descărcate și instalate în mod obișnuit pentru toate componentele clusterului. Per total, distribuția pare foarte interesantă. Sunt sigur că vor fi cei care sunt obișnuiți cu soluții precum Cloudera Manager și Ambari, și cărora le va plăcea însuși ADCM. Pentru unii, va fi, de asemenea, un mare plus că distribuția incluse în registrul software pentru substituirea importurilor.

Dacă vorbim despre dezavantaje, acestea vor fi aceleași ca pentru toate celelalte distribuții Hadoop. Și anume:

  • Așa-numita „blocare a vânzătorului”. Folosind exemplele Cloudera și Hortonworks, ne-am dat deja seama că există întotdeauna riscul de a schimba politica companiei.
  • Întârziere semnificativă în urma Apache în amonte.

Vanilla Hadoop

Apache Bigtop și alegerea unei distribuții Hadoop astăzi

După cum știți, Hadoop nu este un produs monolitic, ci, de fapt, o întreagă galaxie de servicii în jurul sistemului său de fișiere distribuit HDFS. Puțini oameni vor avea suficient de un singur cluster de fișiere. Unii au nevoie de Hive, alții de Presto, iar apoi există HBase și Spark este din ce în ce mai folosit. Pentru orchestrare și încărcare de date, se găsesc uneori Oozie, Sqoop și Flume. Și dacă apare problema securității, atunci îmi vine imediat în minte Kerberos împreună cu Ranger.

Versiunile binare ale componentelor Hadoop sunt disponibile pe site-ul web al fiecărui proiect de ecosistem sub formă de tarball. Puteți să le descărcați și să începeți instalarea, dar cu o condiție: pe lângă asamblarea independentă a pachetelor din binare „brute”, pe care cel mai probabil doriți să le faceți, nu veți avea nicio încredere în compatibilitatea versiunilor descărcate de componente cu fiecare alte. Opțiunea preferată este să construiți folosind Apache Bigtop. Bigtop vă va permite să construiți din depozitele Apache Maven, să rulați teste și să construiți pachete. Dar, ceea ce este foarte important pentru noi, Bigtop va asambla acele versiuni de componente care vor fi compatibile între ele. Vom vorbi despre asta mai detaliat mai jos.

Apache Bigtop

Apache Bigtop și alegerea unei distribuții Hadoop astăzi

Apache Bigtop este un instrument pentru construirea, ambalarea și testarea unui număr de
proiecte open source, cum ar fi Hadoop și Greenplum. Bigtop are o mulțime
eliberează. La momentul scrierii, cea mai recentă versiune stabilă era versiunea 1.4,
iar la master era 1.5. Diferite versiuni de versiuni folosesc versiuni diferite
componente. De exemplu, pentru 1.4 componentele de bază Hadoop au versiunea 2.8.5 și în master
2.10.0. Compoziția componentelor suportate se schimbă și ea. Ceva învechit și
neregenerabilul dispare, iar în locul lui vine ceva nou, mai solicitat și
nu este neapărat ceva din familia Apache în sine.

În plus, Bigtop are multe furci.

Când am început să facem cunoștință cu Bigtop, am fost în primul rând surprinși de modestia lui, în comparație cu alte proiecte Apache, de prevalență și popularitate, precum și de o comunitate foarte mică. De aici rezultă că există informații minime despre produs, iar căutarea de soluții la problemele apărute pe forumuri și liste de corespondență poate să nu aducă absolut nimic. La început, sa dovedit a fi o sarcină dificilă pentru noi să finalizăm ansamblul complet al distribuției datorită caracteristicilor instrumentului în sine, dar despre asta vom vorbi puțin mai târziu.

Ca un teaser, cei care la un moment dat au fost interesați de astfel de proiecte ale universului Linux, cum ar fi Gentoo și LFS, s-ar putea să li se pare nostalgic plăcut să lucreze cu acest lucru și să-și amintească acele vremuri „epice” în care noi înșine căutăm (sau chiar scriam) ebuilds și reconstruit în mod regulat Mozilla cu noi patch-uri.

Marele avantaj al Bigtop este deschiderea și versatilitatea instrumentelor pe care se bazează. Se bazează pe Gradle și Apache Maven. Gradle este destul de bine cunoscut ca instrumentul pe care Google îl folosește pentru a construi Android. Este flexibil și, după cum se spune, „testat de luptă”. Maven este un instrument standard pentru construirea de proiecte în Apache însuși și, deoarece majoritatea produselor sale sunt lansate prin Maven, nici aici nu s-ar putea face fără el. Merită să acordați atenție POM (modelul obiectului de proiect) - un fișier xml „fundamental” care descrie tot ceea ce este necesar pentru ca Maven să lucreze cu proiectul dvs., în jurul căruia este construită toată munca. Exact la
părți din Maven și există câteva obstacole pe care le întâmpină de obicei utilizatorii Bigtop pentru prima dată.

Practică

Deci de unde ar trebui să începi? Accesați pagina de descărcare și descărcați cea mai recentă versiune stabilă ca arhivă. De asemenea, puteți găsi acolo artefacte binare colectate de Bigtop. Apropo, printre managerii obișnuiți de pachete, sunt acceptate YUM și APT.

Alternativ, puteți descărca cea mai recentă versiune stabilă direct de pe
github:

$ git clone --branch branch-1.4 https://github.com/apache/bigtop.git

Clonarea în „bigtop”...

remote: Enumerating objects: 46, done.
remote: Counting objects: 100% (46/46), done.
remote: Compressing objects: 100% (41/41), done.
remote: Total 40217 (delta 14), reused 10 (delta 1), pack-reused 40171
Получение объектов: 100% (40217/40217), 43.54 MiB | 1.05 MiB/s, готово.
Определение изменений: 100% (20503/20503), готово.
Updating files: 100% (1998/1998), готово.

Directorul ./bigtop rezultat arată cam așa:

./bigtop-bigpetstore — aplicații demo, exemple sintetice
./bigtop-ci - Instrumente CI, Jenkins
./bigtop-data-generators — generare de date, sintetice, pentru teste de fum etc.
./bigtop-deploy - instrumente de implementare
./bigtop-packages — configurații, scripturi, patch-uri pentru asamblare, partea principală a instrumentului
./bigtop-test-framework — cadru de testare
./bigtop-tests — testele în sine, încărcare și fum
./bigtop_toolchain — mediu pentru asamblare, pregătirea mediului pentru ca unealta să funcționeze
./build - construiți directorul de lucru
./dl — director pentru sursele descărcate
./docker — construirea imaginilor docker, testare
./gradle - gradle config
./output – directorul în care merg artefactele de construcție
./provisioner — aprovizionare

Cel mai interesant lucru pentru noi în această etapă este configurația principală ./bigtop/bigtop.bom, în care vedem toate componentele acceptate cu versiuni. Aici putem specifica o versiune diferită a produsului (dacă vrem brusc să încercăm să-l construim) sau o versiune de compilare (dacă, de exemplu, am adăugat un patch semnificativ).

Subdirectorul este, de asemenea, de mare interes ./bigtop/bigtop-packages, care este direct legată de procesul de asamblare a componentelor și a pachetelor cu acestea.

Deci, am descărcat arhiva, am despachetat-o ​​sau am făcut o clonă din github, putem începe să construim?

Nu, să pregătim mai întâi mediul.

Pregătirea Mediului

Și aici avem nevoie de o mică retragere. Pentru a construi aproape orice produs mai mult sau mai puțin complex, aveți nevoie de un anumit mediu - în cazul nostru, acesta este JDK, aceleași biblioteci partajate, fișiere de antet etc., instrumente, de exemplu, ant, ivy2 și multe altele. Una dintre opțiunile pentru a obține mediul de care aveți nevoie pentru Bigtop este să instalați componentele necesare pe gazda de compilare. S-ar putea să greșesc în cronologie, dar se pare că cu versiunea 1.0 a existat și o opțiune de a construi imagini Docker preconfigurate și accesibile, care pot fi găsite aici.

În ceea ce privește pregătirea mediului, există un asistent pentru aceasta - Marioneta.

Puteți utiliza următoarele comenzi, rulate din directorul rădăcină
instrument, ./bigtop:

./gradlew toolchain
./gradlew toolchain-devtools
./gradlew toolchain-puppetmodules

Sau direct prin marionetă:

puppet apply --modulepath=<path_to_bigtop> -e "include bigtop_toolchain::installer"
puppet apply --modulepath=<path_to_bigtop> -e "include bigtop_toolchain::deployment-tools"
puppet apply --modulepath=<path_to_bigtop> -e "include bigtop_toolchain::development-tools"

Din păcate, pot apărea dificultăți deja în această etapă. Sfatul general aici este să utilizați o distribuție acceptată, actualizată pe gazda de compilare sau să încercați ruta docker.

asamblare

Ce putem încerca să colectăm? Răspunsul la această întrebare va fi dat de rezultatul comenzii

./gradlew tasks

În secțiunea de sarcini de pachet există o serie de produse care sunt artefacte finale ale Bigtop.
Ele pot fi identificate prin sufixul -rpm sau -pkg-ind (în cazul clădirii
în docker). În cazul nostru, cel mai interesant este Hadoop.

Să încercăm să construim în mediul serverului nostru de compilare:

./gradlew hadoop-rpm

Bigtop însuși va descărca sursele necesare pentru o anumită componentă și va începe asamblarea. Astfel, funcționarea instrumentului depinde de depozitele Maven și de alte surse, adică necesită acces la Internet.

În timpul funcționării, este generată o ieșire standard. Uneori, acesta și mesajele de eroare vă pot ajuta să înțelegeți ce a mers prost. Și uneori trebuie să obțineți informații suplimentare. În acest caz, merită adăugat argumente --info sau --debug, și poate fi, de asemenea, util –stacktrace. Există o modalitate convenabilă de a genera un set de date pentru accesul ulterior la listele de corespondență, cheia --scan.

Cu ajutorul său, bigtop va colecta toate informațiile și le va pune în gradle, după care va oferi un link,
prin urmare, o persoană competentă va putea înțelege de ce a eșuat adunarea.
Vă rugăm să rețineți că această opțiune poate expune informații pe care nu le doriți, cum ar fi nume de utilizator, noduri, variabile de mediu etc., așa că aveți grijă.

Adesea erorile sunt o consecință a incapacității de a obține componentele necesare pentru asamblare. De obicei, puteți rezolva problema creând un patch pentru a remedia ceva în surse, de exemplu, adrese în pom.xml în directorul rădăcină al surselor. Acest lucru se face prin crearea și plasarea acestuia în directorul corespunzător ./bigtop/bigtop-packages/src/common/oozie/ patch, de exemplu, în formă patch2-fix.diff.

--- a/pom.xml
+++ b/pom.xml
@@ -136,7 +136,7 @@
<repositories>
<repository>
<id>central</id>
- <url>http://repo1.maven.org/maven2</url>
+ <url>https://repo1.maven.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>

Cel mai probabil, în momentul citirii acestui articol, nu va trebui să faci singur reparația de mai sus.

Când introduceți patch-uri și modificări ale mecanismului de asamblare, poate fi necesar să „resetati” ansamblul folosind comanda de curățare:

./gradlew hadoop-clean
> Task :hadoop_vardefines
> Task :hadoop-clean
BUILD SUCCESSFUL in 5s
2 actionable tasks: 2 executed

Această operație va derula înapoi toate modificările aduse ansamblului acestei componente, după care asamblarea va fi efectuată din nou. De data aceasta, vom încerca să construim proiectul într-o imagine docker:

./gradlew -POS=centos-7 -Pprefix=1.2.1 hadoop-pkg-ind
> Task :hadoop-pkg-ind
Building 1.2.1 hadoop-pkg on centos-7 in Docker...
+++ dirname ./bigtop-ci/build.sh
++ cd ./bigtop-ci/..
++ pwd
+ BIGTOP_HOME=/tmp/bigtop
+ '[' 6 -eq 0 ']'
+ [[ 6 -gt 0 ]]
+ key=--prefix
+ case $key in
+ PREFIX=1.2.1
+ shift
+ shift
+ [[ 4 -gt 0 ]]
+ key=--os
+ case $key in
+ OS=centos-7
+ shift
+ shift
+ [[ 2 -gt 0 ]]
+ key=--target
+ case $key in
+ TARGET=hadoop-pkg
+ shift
+ shift
+ [[ 0 -gt 0 ]]
+ '[' -z x ']'
+ '[' -z x ']'
+ '[' '' == true ']'
+ IMAGE_NAME=bigtop/slaves:1.2.1-centos-7
++ uname -m
+ ARCH=x86_64
+ '[' x86_64 '!=' x86_64 ']'
++ docker run -d bigtop/slaves:1.2.1-centos-7 /sbin/init
+
CONTAINER_ID=0ce5ac5ca955b822a3e6c5eb3f477f0a152cd27d5487680f77e33fbe66b5bed8
+ trap 'docker rm -f
0ce5ac5ca955b822a3e6c5eb3f477f0a152cd27d5487680f77e33fbe66b5bed8' EXIT
....
много вывода
....
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-hdfs-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-yarn-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-mapreduce-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-hdfs-namenode-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-hdfs-secondarynamenode-2.8.5-
1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-hdfs-zkfc-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-hdfs-journalnode-2.8.5-
1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-hdfs-datanode-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-httpfs-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-yarn-resourcemanager-2.8.5-
1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-yarn-nodemanager-2.8.5-
1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-yarn-proxyserver-2.8.5-
1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-yarn-timelineserver-2.8.5-
1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-mapreduce-historyserver-2.8.5-
1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-client-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-conf-pseudo-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-doc-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-libhdfs-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-libhdfs-devel-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-hdfs-fuse-2.8.5-1.el7.x86_64.rpm
Wrote: /bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-debuginfo-2.8.5-1.el7.x86_64.rpm
+ umask 022
+ cd /bigtop/build/hadoop/rpm//BUILD
+ cd hadoop-2.8.5-src
+ /usr/bin/rm -rf /bigtop/build/hadoop/rpm/BUILDROOT/hadoop-2.8.5-1.el7.x86_64
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.uQ2FCn
+ exit 0
+ umask 022
Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.CwDb22
+ cd /bigtop/build/hadoop/rpm//BUILD
+ rm -rf hadoop-2.8.5-src
+ exit 0
[ant:touch] Creating /bigtop/build/hadoop/.rpm
:hadoop-rpm (Thread[Task worker for ':',5,main]) completed. Took 38 mins 1.151 secs.
:hadoop-pkg (Thread[Task worker for ':',5,main]) started.
> Task :hadoop-pkg
Task ':hadoop-pkg' is not up-to-date because:
Task has not declared any outputs despite executing actions.
:hadoop-pkg (Thread[Task worker for ':',5,main]) completed. Took 0.0 secs.
BUILD SUCCESSFUL in 40m 37s
6 actionable tasks: 6 executed
+ RESULT=0
+ mkdir -p output
+ docker cp
ac46014fd9501bdc86b6c67d08789fbdc6ee46a2645550ff6b6712f7d02ffebb:/bigtop/build .
+ docker cp
ac46014fd9501bdc86b6c67d08789fbdc6ee46a2645550ff6b6712f7d02ffebb:/bigtop/output .
+ docker rm -f ac46014fd9501bdc86b6c67d08789fbdc6ee46a2645550ff6b6712f7d02ffebb
ac46014fd9501bdc86b6c67d08789fbdc6ee46a2645550ff6b6712f7d02ffebb
+ '[' 0 -ne 0 ']'
+ docker rm -f ac46014fd9501bdc86b6c67d08789fbdc6ee46a2645550ff6b6712f7d02ffebb
Error: No such container:
ac46014fd9501bdc86b6c67d08789fbdc6ee46a2645550ff6b6712f7d02ffebb
BUILD SUCCESSFUL in 41m 24s
1 actionable task: 1 executed

Construirea a fost realizată sub CentOS, dar poate fi făcută și sub Ubuntu:

./gradlew -POS=ubuntu-16.04 -Pprefix=1.2.1 hadoop-pkg-ind

Pe lângă construirea de pachete pentru diverse distribuții Linux, instrumentul poate crea un depozit cu pachete compilate, de exemplu:

./gradlew yum

De asemenea, vă puteți aminti despre testele de fum și implementarea în Docker.

Creați un grup de trei noduri:

./gradlew -Pnum_instances=3 docker-provisioner

Efectuați teste de fum într-un grup de trei noduri:

./gradlew -Pnum_instances=3 -Prun_smoke_tests docker-provisioner

Ștergeți un cluster:

./gradlew docker-provisioner-destroy

Obțineți comenzi pentru conectarea în interiorul containerelor docker:

./gradlew docker-provisioner-ssh

Arată starea:

./gradlew docker-provisioner-status

Puteți citi mai multe despre sarcinile de implementare în documentație.

Dacă vorbim de teste, există un număr destul de mare de ele, în principal fum și integrare. Analiza lor depășește scopul acestui articol. Permiteți-mi să spun doar că asamblarea unui kit de distribuție nu este o sarcină atât de dificilă pe cât ar părea la prima vedere. Am reușit să asamblam și să trecem teste pe toate componentele pe care le folosim în producția noastră și, de asemenea, nu am avut probleme la implementarea acestora și la efectuarea operațiunilor de bază în mediul de testare.

Pe lângă componentele existente în Bigtop, este posibil să adăugați orice altceva, chiar și propria dezvoltare de software. Toate acestea sunt perfect automatizate și se încadrează în conceptul CI/CD.

Concluzie

Evident, distribuția astfel compilată nu trebuie trimisă imediat în producție. Trebuie să înțelegeți că, dacă există o nevoie reală de a vă construi și susține distribuția, atunci trebuie să investiți bani și timp în asta.

Cu toate acestea, în combinație cu abordarea corectă și cu o echipă profesionistă, este foarte posibil să se facă fără soluții comerciale.

Este important de menționat că proiectul Bigtop în sine are nevoie de dezvoltare și nu pare să fie dezvoltat în mod activ astăzi. Perspectiva ca Hadoop 3 să apară în el este, de asemenea, neclară, dacă aveți o nevoie reală de a construi Hadoop 3 furculiţă de la Arenadata, în care, pe lângă standard
Există o serie de componente suplimentare (Ranger, Knox, NiFi).

Cât despre Rostelecom, pentru noi Bigtop este una dintre opțiunile luate în considerare astăzi. Indiferent dacă o alegem sau nu, timpul ne va spune.

Apendice

Pentru a include o componentă nouă în ansamblu, trebuie să adăugați descrierea acesteia la bigtop.bom și ./bigtop-packages. Puteți încerca să faceți acest lucru prin analogie cu componentele existente. Încercați să vă dați seama. Nu este atât de dificil pe cât pare la prima vedere.

Ce crezi? Vom fi bucuroși să vedem părerea dumneavoastră în comentarii și vă mulțumim pentru atenție!

Articolul a fost pregătit de echipa de management al datelor Rostelecom

Sursa: www.habr.com

Adauga un comentariu