├── .DS_Store ├── .gitignore ├── AIRFLOW ├── README.md └── task │ ├── docker-compose.yaml │ └── test_task.py ├── CASES └── README.md ├── CLICKHOUSE ├── Dop_mat │ ├── clickhouse-cluster │ │ ├── Makefile │ │ ├── README.md │ │ ├── clickhouse01 │ │ │ ├── config.xml │ │ │ └── users.xml │ │ ├── clickhouse02 │ │ │ ├── config.xml │ │ │ └── users.xml │ │ ├── clickhouse03 │ │ │ ├── config.xml │ │ │ └── users.xml │ │ ├── clickhouse04 │ │ │ ├── config.xml │ │ │ └── users.xml │ │ ├── config.xml │ │ ├── docker-compose.yml │ │ └── users.xml │ └── clickhouse-cone_node │ │ └── docker-compose.yaml └── README.md ├── CONTRIBUTING.md ├── DBT ├── README.md └── images │ ├── bereal-2024-10-10-0825.jpeg │ ├── image-1.png │ ├── image-2.png │ └── image.png ├── DM └── README.md ├── DOCKER ├── README.md └── VM │ └── README.md ├── DWH ├── Additional_information │ └── ACID │ │ └── README.md └── README.md ├── GREENPLUM ├── CASES_OPTIMIZATION │ └── README.md └── README.md ├── Git └── README.md ├── HADOOP ├── ECOSYSTEM_HADOOP │ └── README.md └── README.md ├── Indexes_and_partitions └── README.md ├── JOB └── README.md ├── KAFKA └── README.md ├── Linux └── README.md ├── NF └── README.md ├── PET_PROJECT └── README.md ├── QUESTION ├── AirFlow │ └── README.md ├── ClickHouse │ └── README.md ├── DWH │ └── README.md ├── Data_Base │ └── README.md ├── GreenPlum │ └── README.md ├── Hadoop │ └── README.md ├── PySpark │ └── README.md ├── Python │ └── README.md ├── README.md └── SQL │ └── README.md ├── README.md ├── Resume └── README.md ├── SPARK ├── ADVANCED │ ├── ARCHITECTURE │ │ └── README.md │ └── README.md ├── ARCHITECTURE │ └── README.md └── BASE │ └── README.md ├── change_log ├── files ├── Apache Airflow.pdf ├── data_vault.pdf ├── deep_dive_hdfs_pdf.pdf ├── greenplum.pdf └── normal_tables.pdf └── png ├── Apache_Kafka.png ├── BASH_logo.png ├── CH_col_oriented.jpg ├── af_arfitecture.png ├── af_connection.png ├── af_dag.png ├── af_final_task.png ├── af_start_page.png ├── airflow_logo.jpg ├── amp.jpg ├── batch.png ├── cases.jpg ├── ch_column_oriented.gif ├── ch_filename.jpg ├── ch_filename.png ├── ch_filename.png.jpg ├── ch_logo.jpg ├── ch_mater_col.png ├── ch_merge.gif ├── ch_minmax.jpg ├── ch_minmax.png ├── ch_no_column.png ├── ch_partition.jpg ├── ch_set_idx.jpg ├── ch_table.jpg ├── data_mart.jpeg ├── data_warehouse.png ├── dbt_logo.png ├── de1.jpg ├── de1.png ├── de2.png ├── de3.png ├── de4.png ├── de5.png ├── docker_logo.png ├── dv.png ├── dwh.png ├── dwh_ai_acid_dirty_reading.png ├── dwh_ai_acid_lost_data.png ├── dwh_ai_acid_non_repetitive_reading.png ├── dwh_ai_acid_phantom_reading.png ├── exp.png ├── git_fork.png ├── git_fork2.png ├── git_github.png ├── git_ssh.png ├── git_ssh2.png ├── git_ssh3.png ├── github_pics.jpg ├── gp_advanced_mirrors.png ├── gp_advanced_mirrors_fail.png ├── gp_ao_colum_orientir.png ├── gp_ao_string_orientir.png ├── gp_ao_table.png ├── gp_arhitecture.png ├── gp_b_tree.png ├── gp_distributed_broadcast.png ├── gp_distributed_by_key.png ├── gp_distributed_random.png ├── gp_explain.png ├── gp_explain_analyze.png ├── gp_external_table.png ├── gp_gpfgist.png ├── gp_group_mirrors.png ├── gp_group_mirrors_fail.png ├── gp_heap_table.png ├── gp_inc.jpg ├── gp_index.png ├── gp_logo.png ├── gp_master_fail.png ├── gp_mirrors_master.png ├── gp_mpp.png ├── gp_partitions.png ├── gp_partitions_comb.png ├── gp_partitions_list.png ├── gp_partitions_range.png ├── gp_pxf.png ├── gp_simple_load_save_data.png ├── gp_sql_operations.png ├── hadoop_arch.png ├── hadoop_logo.png ├── hadoop_rep.png ├── hadoop_secondary.png ├── halltape.jpg ├── ind_part_logo.png ├── indexes_and_partitions ├── ind_bitmap1.png ├── ind_bitmap2.png ├── ind_bitmap3.png ├── ind_btree.png ├── ind_btree_revers1.png ├── ind_btree_revers2.png ├── ind_clust_vs_non_clust.png ├── ind_hash.png ├── ind_part_bag.png ├── ind_part_three_bags.png └── partitions.png ├── inmon.png ├── intern.png ├── kafka_logo.png ├── kafka_producers.png ├── kappa.png ├── kimbal.png ├── lakehouse.png ├── lambda.png ├── links.jpeg ├── mail_pet_project.gif ├── models_data.jpeg ├── normal.jpg ├── normal_table.jpg ├── olap_oltp.png ├── pengwin.jpg ├── pet_project.png ├── pp_2.png ├── que.jpg ├── resume.jpg ├── shust.jpg ├── snowflake.png ├── spark.png ├── spark_arch.png ├── spark_catalyst.jpg ├── spark_eco.png ├── spark_images ├── SPARK.001.jpeg ├── SPARK.002.jpeg ├── SPARK.003.jpeg ├── SPARK.004.jpeg ├── SPARK.005.jpeg ├── SPARK.006.jpeg ├── SPARK.007.jpeg ├── SPARK.008.jpeg ├── SPARK.009.jpeg ├── SPARK.010.jpeg ├── SPARK.011.jpeg ├── SPARK.012.jpeg ├── SPARK.013.jpeg └── spark_ui.png ├── spark_join.jpg ├── spark_logo.png ├── spark_stages.jpg ├── star.png ├── stream.png ├── yarn.png ├── yarn_eco.png └── yarn_map_reduce.jpg /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | **/venv/ 4 | **/.venv/ 5 | **/jaffle_shop_duckdb/ -------------------------------------------------------------------------------- /AIRFLOW/task/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | x-airflow-common: 3 | &airflow-common 4 | image: ${AIRFLOW_IMAGE_NAME:-apache/airflow:2.10.3} 5 | environment: 6 | &airflow-common-env 7 | AIRFLOW__CORE__EXECUTOR: CeleryExecutor 8 | AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow@postgres/airflow 9 | AIRFLOW__CELERY__RESULT_BACKEND: db+postgresql://airflow:airflow@postgres/airflow 10 | AIRFLOW__CELERY__BROKER_URL: redis://:@redis:6379/0 11 | AIRFLOW__CORE__FERNET_KEY: '' 12 | AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION: 'true' 13 | AIRFLOW__CORE__LOAD_EXAMPLES: 'false' 14 | AIRFLOW__API__AUTH_BACKENDS: 'airflow.api.auth.backend.basic_auth,airflow.api.auth.backend.session' 15 | AIRFLOW__SCHEDULER__ENABLE_HEALTH_CHECK: 'true' 16 | AIRFLOW__CORE__TEST_CONNECTION: 'Enabled' 17 | _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-} 18 | volumes: 19 | - ${AIRFLOW_PROJ_DIR:-.}/dags:/opt/airflow/dags 20 | - ${AIRFLOW_PROJ_DIR:-.}/logs:/opt/airflow/logs 21 | - ${AIRFLOW_PROJ_DIR:-.}/config:/opt/airflow/config 22 | - ${AIRFLOW_PROJ_DIR:-.}/plugins:/opt/airflow/plugins 23 | user: "${AIRFLOW_UID:-50000}:0" 24 | depends_on: 25 | &airflow-common-depends-on 26 | redis: 27 | condition: service_healthy 28 | postgres: 29 | condition: service_healthy 30 | 31 | services: 32 | postgres: 33 | image: postgres:13 34 | environment: 35 | POSTGRES_USER: airflow 36 | POSTGRES_PASSWORD: airflow 37 | POSTGRES_DB: airflow 38 | volumes: 39 | - postgres-db-volume:/var/lib/postgresql/data 40 | healthcheck: 41 | test: ["CMD", "pg_isready", "-U", "airflow"] 42 | interval: 10s 43 | retries: 5 44 | start_period: 5s 45 | restart: always 46 | 47 | redis: 48 | image: redis:7.2-bookworm 49 | expose: 50 | - 6379 51 | healthcheck: 52 | test: ["CMD", "redis-cli", "ping"] 53 | interval: 10s 54 | timeout: 30s 55 | retries: 50 56 | start_period: 30s 57 | restart: always 58 | 59 | airflow-webserver: 60 | <<: *airflow-common 61 | command: webserver 62 | ports: 63 | - "8080:8080" 64 | healthcheck: 65 | test: ["CMD", "curl", "--fail", "http://localhost:8080/health"] 66 | interval: 30s 67 | timeout: 10s 68 | retries: 5 69 | start_period: 30s 70 | restart: always 71 | depends_on: 72 | <<: *airflow-common-depends-on 73 | airflow-init: 74 | condition: service_completed_successfully 75 | 76 | airflow-scheduler: 77 | <<: *airflow-common 78 | command: scheduler 79 | healthcheck: 80 | test: ["CMD", "curl", "--fail", "http://localhost:8974/health"] 81 | interval: 30s 82 | timeout: 10s 83 | retries: 5 84 | start_period: 30s 85 | restart: always 86 | depends_on: 87 | <<: *airflow-common-depends-on 88 | airflow-init: 89 | condition: service_completed_successfully 90 | 91 | airflow-worker: 92 | <<: *airflow-common 93 | command: celery worker 94 | healthcheck: 95 | test: 96 | - "CMD-SHELL" 97 | - 'celery --app airflow.providers.celery.executors.celery_executor.app inspect ping -d "celery@$${HOSTNAME}" || celery --app airflow.executors.celery_executor.app inspect ping -d "celery@$${HOSTNAME}"' 98 | interval: 30s 99 | timeout: 10s 100 | retries: 5 101 | start_period: 30s 102 | environment: 103 | <<: *airflow-common-env 104 | DUMB_INIT_SETSID: "0" 105 | restart: always 106 | depends_on: 107 | <<: *airflow-common-depends-on 108 | airflow-init: 109 | condition: service_completed_successfully 110 | 111 | airflow-triggerer: 112 | <<: *airflow-common 113 | command: triggerer 114 | healthcheck: 115 | test: ["CMD-SHELL", 'airflow jobs check --job-type TriggererJob --hostname "$${HOSTNAME}"'] 116 | interval: 30s 117 | timeout: 10s 118 | retries: 5 119 | start_period: 30s 120 | restart: always 121 | depends_on: 122 | <<: *airflow-common-depends-on 123 | airflow-init: 124 | condition: service_completed_successfully 125 | 126 | airflow-init: 127 | <<: *airflow-common 128 | entrypoint: /bin/bash 129 | command: 130 | - -c 131 | - | 132 | if [[ -z "${AIRFLOW_UID}" ]]; then 133 | echo 134 | echo -e "\033[1;33mWARNING!!!: AIRFLOW_UID not set!\e[0m" 135 | echo "If you are on Linux, you SHOULD follow the instructions below to set " 136 | echo "AIRFLOW_UID environment variable, otherwise files will be owned by root." 137 | echo "For other operating systems you can get rid of the warning with manually created .env file:" 138 | echo " See: https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html#setting-the-right-airflow-user" 139 | echo 140 | fi 141 | one_meg=1048576 142 | mem_available=$$(($$(getconf _PHYS_PAGES) * $$(getconf PAGE_SIZE) / one_meg)) 143 | cpus_available=$$(grep -cE 'cpu[0-9]+' /proc/stat) 144 | disk_available=$$(df / | tail -1 | awk '{print $$4}') 145 | warning_resources="false" 146 | if (( mem_available < 4000 )) ; then 147 | echo 148 | echo -e "\033[1;33mWARNING!!!: Not enough memory available for Docker.\e[0m" 149 | echo "At least 4GB of memory required. You have $$(numfmt --to iec $$((mem_available * one_meg)))" 150 | echo 151 | warning_resources="true" 152 | fi 153 | if (( cpus_available < 2 )); then 154 | echo 155 | echo -e "\033[1;33mWARNING!!!: Not enough CPUS available for Docker.\e[0m" 156 | echo "At least 2 CPUs recommended. You have $${cpus_available}" 157 | echo 158 | warning_resources="true" 159 | fi 160 | if (( disk_available < one_meg * 10 )); then 161 | echo 162 | echo -e "\033[1;33mWARNING!!!: Not enough Disk space available for Docker.\e[0m" 163 | echo "At least 10 GBs recommended. You have $$(numfmt --to iec $$((disk_available * 1024 )))" 164 | echo 165 | warning_resources="true" 166 | fi 167 | if [[ $${warning_resources} == "true" ]]; then 168 | echo 169 | echo -e "\033[1;33mWARNING!!!: You have not enough resources to run Airflow (see above)!\e[0m" 170 | echo "Please follow the instructions to increase amount of resources available:" 171 | echo " https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html#before-you-begin" 172 | echo 173 | fi 174 | mkdir -p /sources/logs /sources/dags /sources/plugins 175 | chown -R "${AIRFLOW_UID}:0" /sources/{logs,dags,plugins} 176 | exec /entrypoint airflow version 177 | environment: 178 | <<: *airflow-common-env 179 | _AIRFLOW_DB_MIGRATE: 'true' 180 | _AIRFLOW_WWW_USER_CREATE: 'true' 181 | _AIRFLOW_WWW_USER_USERNAME: ${_AIRFLOW_WWW_USER_USERNAME:-airflow} 182 | _AIRFLOW_WWW_USER_PASSWORD: ${_AIRFLOW_WWW_USER_PASSWORD:-airflow} 183 | _PIP_ADDITIONAL_REQUIREMENTS: '' 184 | user: "0:0" 185 | volumes: 186 | - ${AIRFLOW_PROJ_DIR:-.}:/sources 187 | 188 | airflow-cli: 189 | <<: *airflow-common 190 | profiles: 191 | - debug 192 | environment: 193 | <<: *airflow-common-env 194 | CONNECTION_CHECK_MAX_COUNT: "0" 195 | command: 196 | - bash 197 | - -c 198 | - airflow 199 | 200 | flower: 201 | <<: *airflow-common 202 | command: celery flower 203 | profiles: 204 | - flower 205 | ports: 206 | - "5555:5555" 207 | healthcheck: 208 | test: ["CMD", "curl", "--fail", "http://localhost:5555/"] 209 | interval: 30s 210 | timeout: 10s 211 | retries: 5 212 | start_period: 30s 213 | restart: always 214 | depends_on: 215 | <<: *airflow-common-depends-on 216 | airflow-init: 217 | condition: service_completed_successfully 218 | 219 | server_psql: 220 | image: postgres:14 221 | container_name: server_psql 222 | restart: always 223 | ports: 224 | - '5431:5432' 225 | environment: 226 | POSTGRES_USER: user 227 | POSTGRES_PASSWORD: user 228 | POSTGRES_DB: user 229 | 230 | volumes: 231 | postgres-db-volume: 232 | -------------------------------------------------------------------------------- /AIRFLOW/task/test_task.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, timedelta 2 | from airflow import DAG 3 | from airflow.operators.python import PythonOperator 4 | from airflow.operators.bash import BashOperator 5 | from airflow.providers.postgres.operators.postgres import PostgresOperator 6 | from hashlib import md5 7 | from sqlalchemy import create_engine 8 | import pandas as pd 9 | 10 | 11 | default_args = { 12 | 'owner': '@Shust_DE', 13 | 'depends_on_past': False, 14 | 'start_date': datetime(2024, 11, 13), 15 | 'email': ['https://t.me/Shust_DE'], 16 | 'schedule_interval': "@hourly", 17 | } 18 | 19 | 20 | def _generate_file(**kwargs): 21 | ti = kwargs['ti'] 22 | path_filename = '/tmp/data.csv' 23 | table = [(i, md5(int(i).to_bytes(8, 'big', signed=True)).hexdigest()) for i in range(1, 100)] 24 | table = pd.DataFrame(table, columns=['id', 'md5_id']) 25 | table.to_csv(path_filename, index=False) 26 | ti.xcom_push(key='path_file', value=path_filename) 27 | 28 | 29 | def _data_in_postgres(**kwargs): 30 | ti = kwargs['ti'] 31 | df = pd.read_csv("/tmp/processed_data/data.csv") 32 | engine = create_engine('postgresql://user:user@host.docker.internal:5431/user') 33 | df.to_sql('table_name', engine, if_exists='append', schema='public', index=False) 34 | ti.xcom_push(key='count_string', value=len(df)) 35 | 36 | 37 | dag = DAG( 38 | dag_id="load_file_to_psql", 39 | default_args=default_args 40 | ) 41 | 42 | generate_file = PythonOperator( 43 | task_id='generate_file', 44 | python_callable=_generate_file, 45 | dag=dag, 46 | ) 47 | 48 | 49 | move_data_file = BashOperator( 50 | task_id="move_data_file", 51 | bash_command=("mkdir -p /tmp/processed_data/ && " 52 | "mv {{ ti.xcom_pull(task_ids='generate_file', key='path_file') }} /tmp/processed_data/"), 53 | dag=dag, 54 | ) 55 | 56 | 57 | create_table_psql = PostgresOperator( 58 | task_id='create_table', 59 | postgres_conn_id='psql_connection', 60 | sql=""" DROP TABLE IF EXISTS table_name; 61 | CREATE TABLE table_name ( id int, 62 | md5_id text); """ 63 | ) 64 | 65 | 66 | data_in_postgres = PythonOperator( 67 | task_id='data_in_postgres', 68 | python_callable=_data_in_postgres, 69 | dag=dag, 70 | ) 71 | 72 | 73 | print_count_string_in_df = BashOperator( 74 | task_id="print_count_string_in_df", 75 | bash_command=('''echo "В таблице {{ ti.xcom_pull(task_ids='data_in_postgres', key='count_string') }} строк" '''), 76 | dag=dag, 77 | ) 78 | 79 | 80 | ( 81 | generate_file >> 82 | move_data_file >> 83 | create_table_psql >> 84 | data_in_postgres >> 85 | print_count_string_in_df 86 | ) 87 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: config 2 | config: 3 | rm -rf clickhouse01 clickhouse02 clickhouse03 clickhouse04 4 | mkdir -p clickhouse01 clickhouse02 clickhouse03 clickhouse04 5 | REPLICA=01 SHARD=01 envsubst < config.xml > clickhouse01/config.xml 6 | REPLICA=02 SHARD=01 envsubst < config.xml > clickhouse02/config.xml 7 | REPLICA=03 SHARD=02 envsubst < config.xml > clickhouse03/config.xml 8 | REPLICA=04 SHARD=02 envsubst < config.xml > clickhouse04/config.xml 9 | cp users.xml clickhouse01/users.xml 10 | cp users.xml clickhouse02/users.xml 11 | cp users.xml clickhouse03/users.xml 12 | cp users.xml clickhouse04/users.xml 13 | 14 | .PHONY: up 15 | up: 16 | docker-compose up -d 17 | 18 | .PHONY: start 19 | start: 20 | docker-compose start 21 | 22 | .PHONY: stop 23 | stop: 24 | docker-compose stop 25 | 26 | .PHONY: down 27 | down: 28 | docker-compose down 29 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/README.md: -------------------------------------------------------------------------------- 1 | # Clickhouse Cluster 2 | 3 | Кластер Clickhouse был честно спизжен с данного ресурса, ибо нахер придумывать велосипед когда и так всё хорошо работает 4 | 5 | ## Запуск 6 | 7 | Установите пакет **make** и перейдите в каталог с кластером. 8 | 9 | ```sh 10 | sudo apt install make 11 | ``` 12 | 13 | Для поднятия всего кластера необходимо выполнить одну единственную команду: 14 | 15 | ```sh 16 | make config up 17 | ``` 18 | 19 | В итоге поднимится кластер с именем `company_cluster`. 20 | 21 | Контейнер находится в сети `172.23.0.0/24` (эта инфа нужна если вы делаете пет-проект и вы разграничиваете сети) 22 | 23 | | Container | Address 24 | | ------------ | ------- 25 | | zookeeper | 172.23.0.10 26 | | clickhouse01 | 172.23.0.11 27 | | clickhouse02 | 172.23.0.12 28 | | clickhouse03 | 172.23.0.13 29 | | clickhouse04 | 172.23.0.14 30 | 31 | ## Профиля 32 | 33 | - `default` - no password 34 | - `admin` - password `123` 35 | 36 | ## Пример подключения через DBeaver 37 | 38 |

39 | Пример подключения 40 |

41 | 42 | ## Старт и останвка 43 | 44 | Старт и остановка контейнерос 45 | ```sh 46 | make start 47 | make stop 48 | ``` 49 | 50 | ## Полная остановка 51 | 52 | Полная остановка с удалением контейнера 53 | ```sh 54 | make down 55 | ``` 56 | ## Дополнительная конфигурация 57 | 58 | Полазте по проекту, там нет абсолютно ничего сложного. Если захотите настройте его под себя. 59 | 60 | А с другоой стороны: 61 | 62 | [![Не лезь бл*ть оно тебя сожрёт](https://markdown-videos-api.jorgenkh.no/youtube/rTSODCT4mKw)](https://www.youtube.com/watch?v=oqRuyaVv_0A&list=PLYtH_gZiwIjiKTGP-4gI75NL4fTXZHker&rco=1) -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/clickhouse01/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | true 6 | 7 | 8 | 9 | 10 | 11 | system 12 | query_log
13 |
14 | 15 | 0.0.0.0 16 | 8123 17 | 9000 18 | clickhouse01 19 | 9009 20 | 21 | 4096 22 | 3 23 | 100 24 | 8589934592 25 | 5368709120 26 | 27 | /var/lib/clickhouse/ 28 | /var/lib/clickhouse/tmp/ 29 | /var/lib/clickhouse/user_files/ 30 | 31 | users.xml 32 | default 33 | default 34 | Europe/Moscow 35 | false 36 | 37 | 38 | 39 | 40 | 41 | clickhouse01 42 | 9000 43 | 44 | 45 | clickhouse02 46 | 9000 47 | 48 | 49 | 50 | 51 | clickhouse03 52 | 9000 53 | 54 | 55 | clickhouse04 56 | 9000 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | zookeeper 65 | 2181 66 | 67 | 68 | 69 | 70 | company_cluster 71 | 01 72 | clickhouse01 73 | 74 | 75 | 76 | /clickhouse/task_queue/ddl 77 | 78 | 79 | /var/lib/clickhouse/format_schemas/ 80 |
81 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/clickhouse01/users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10000000000 6 | 0 7 | in_order 8 | 1 9 | 10 | 11 | 12 | 13 | 14 | 15 | default 16 | 17 | ::/0 18 | 19 | default 20 | 21 | 22 | 123 23 | default 24 | 25 | ::/0 26 | 27 | default 28 | 29 | 30 | 31 | 32 | 33 | 34 | 3600 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/clickhouse02/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | true 6 | 7 | 8 | 9 | 10 | 11 | system 12 | query_log
13 |
14 | 15 | 0.0.0.0 16 | 8123 17 | 9000 18 | clickhouse02 19 | 9009 20 | 21 | 4096 22 | 3 23 | 100 24 | 8589934592 25 | 5368709120 26 | 27 | /var/lib/clickhouse/ 28 | /var/lib/clickhouse/tmp/ 29 | /var/lib/clickhouse/user_files/ 30 | 31 | users.xml 32 | default 33 | default 34 | Europe/Moscow 35 | false 36 | 37 | 38 | 39 | 40 | 41 | clickhouse01 42 | 9000 43 | 44 | 45 | clickhouse02 46 | 9000 47 | 48 | 49 | 50 | 51 | clickhouse03 52 | 9000 53 | 54 | 55 | clickhouse04 56 | 9000 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | zookeeper 65 | 2181 66 | 67 | 68 | 69 | 70 | company_cluster 71 | 01 72 | clickhouse02 73 | 74 | 75 | 76 | /clickhouse/task_queue/ddl 77 | 78 | 79 | /var/lib/clickhouse/format_schemas/ 80 |
81 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/clickhouse02/users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10000000000 6 | 0 7 | in_order 8 | 1 9 | 10 | 11 | 12 | 13 | 14 | 15 | default 16 | 17 | ::/0 18 | 19 | default 20 | 21 | 22 | 123 23 | default 24 | 25 | ::/0 26 | 27 | default 28 | 29 | 30 | 31 | 32 | 33 | 34 | 3600 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/clickhouse03/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | true 6 | 7 | 8 | 9 | 10 | 11 | system 12 | query_log
13 |
14 | 15 | 0.0.0.0 16 | 8123 17 | 9000 18 | clickhouse03 19 | 9009 20 | 21 | 4096 22 | 3 23 | 100 24 | 8589934592 25 | 5368709120 26 | 27 | /var/lib/clickhouse/ 28 | /var/lib/clickhouse/tmp/ 29 | /var/lib/clickhouse/user_files/ 30 | 31 | users.xml 32 | default 33 | default 34 | Europe/Moscow 35 | false 36 | 37 | 38 | 39 | 40 | 41 | clickhouse01 42 | 9000 43 | 44 | 45 | clickhouse02 46 | 9000 47 | 48 | 49 | 50 | 51 | clickhouse03 52 | 9000 53 | 54 | 55 | clickhouse04 56 | 9000 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | zookeeper 65 | 2181 66 | 67 | 68 | 69 | 70 | company_cluster 71 | 02 72 | clickhouse03 73 | 74 | 75 | 76 | /clickhouse/task_queue/ddl 77 | 78 | 79 | /var/lib/clickhouse/format_schemas/ 80 |
81 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/clickhouse03/users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10000000000 6 | 0 7 | in_order 8 | 1 9 | 10 | 11 | 12 | 13 | 14 | 15 | default 16 | 17 | ::/0 18 | 19 | default 20 | 21 | 22 | 123 23 | default 24 | 25 | ::/0 26 | 27 | default 28 | 29 | 30 | 31 | 32 | 33 | 34 | 3600 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/clickhouse04/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | true 6 | 7 | 8 | 9 | 10 | 11 | system 12 | query_log
13 |
14 | 15 | 0.0.0.0 16 | 8123 17 | 9000 18 | clickhouse04 19 | 9009 20 | 21 | 4096 22 | 3 23 | 100 24 | 8589934592 25 | 5368709120 26 | 27 | /var/lib/clickhouse/ 28 | /var/lib/clickhouse/tmp/ 29 | /var/lib/clickhouse/user_files/ 30 | 31 | users.xml 32 | default 33 | default 34 | Europe/Moscow 35 | false 36 | 37 | 38 | 39 | 40 | 41 | clickhouse01 42 | 9000 43 | 44 | 45 | clickhouse02 46 | 9000 47 | 48 | 49 | 50 | 51 | clickhouse03 52 | 9000 53 | 54 | 55 | clickhouse04 56 | 9000 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | zookeeper 65 | 2181 66 | 67 | 68 | 69 | 70 | company_cluster 71 | 02 72 | clickhouse04 73 | 74 | 75 | 76 | /clickhouse/task_queue/ddl 77 | 78 | 79 | /var/lib/clickhouse/format_schemas/ 80 |
81 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/clickhouse04/users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10000000000 6 | 0 7 | in_order 8 | 1 9 | 10 | 11 | 12 | 13 | 14 | 15 | default 16 | 17 | ::/0 18 | 19 | default 20 | 21 | 22 | 123 23 | default 24 | 25 | ::/0 26 | 27 | default 28 | 29 | 30 | 31 | 32 | 33 | 34 | 3600 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | true 6 | 7 | 8 | 9 | 10 | 11 | system 12 | query_log
13 |
14 | 15 | 0.0.0.0 16 | 8123 17 | 9000 18 | clickhouse${REPLICA} 19 | 9009 20 | 21 | 4096 22 | 3 23 | 100 24 | 8589934592 25 | 5368709120 26 | 27 | /var/lib/clickhouse/ 28 | /var/lib/clickhouse/tmp/ 29 | /var/lib/clickhouse/user_files/ 30 | 31 | users.xml 32 | default 33 | default 34 | Europe/Moscow 35 | false 36 | 37 | 38 | 39 | 40 | 41 | clickhouse01 42 | 9000 43 | 44 | 45 | clickhouse02 46 | 9000 47 | 48 | 49 | 50 | 51 | clickhouse03 52 | 9000 53 | 54 | 55 | clickhouse04 56 | 9000 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | zookeeper 65 | 2181 66 | 67 | 68 | 69 | 70 | company_cluster 71 | ${SHARD} 72 | clickhouse${REPLICA} 73 | 74 | 75 | 76 | /clickhouse/task_queue/ddl 77 | 78 | 79 | /var/lib/clickhouse/format_schemas/ 80 |
81 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | zookeeper: 4 | image: zookeeper:3.7 5 | container_name: zookeeper 6 | hostname: zookeeper 7 | networks: 8 | clickhouse-network: 9 | ipv4_address: 172.23.0.10 10 | clickhouse01: 11 | image: clickhouse/clickhouse-server:22.5 12 | container_name: clickhouse01 13 | hostname: clickhouse01 14 | networks: 15 | clickhouse-network: 16 | ipv4_address: 172.23.0.11 17 | ports: 18 | - "127.0.0.1:8123:8123" 19 | - "127.0.0.1:9000:9000" 20 | volumes: 21 | - ${PWD}/clickhouse01:/etc/clickhouse-server 22 | depends_on: 23 | - zookeeper 24 | clickhouse02: 25 | image: clickhouse/clickhouse-server:22.5 26 | container_name: clickhouse02 27 | hostname: clickhouse02 28 | networks: 29 | clickhouse-network: 30 | ipv4_address: 172.23.0.12 31 | volumes: 32 | - ${PWD}/clickhouse02:/etc/clickhouse-server 33 | depends_on: 34 | - zookeeper 35 | clickhouse03: 36 | image: clickhouse/clickhouse-server:22.5 37 | container_name: clickhouse03 38 | hostname: clickhouse03 39 | networks: 40 | clickhouse-network: 41 | ipv4_address: 172.23.0.13 42 | volumes: 43 | - ${PWD}/clickhouse03:/etc/clickhouse-server 44 | depends_on: 45 | - zookeeper 46 | clickhouse04: 47 | image: clickhouse/clickhouse-server:22.5 48 | container_name: clickhouse04 49 | hostname: clickhouse04 50 | networks: 51 | clickhouse-network: 52 | ipv4_address: 172.23.0.14 53 | volumes: 54 | - ${PWD}/clickhouse04:/etc/clickhouse-server 55 | depends_on: 56 | - zookeeper 57 | 58 | networks: 59 | clickhouse-network: 60 | name: clickhouse-network 61 | ipam: 62 | config: 63 | - subnet: 172.23.0.0/24 64 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cluster/users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10000000000 6 | 0 7 | in_order 8 | 1 9 | 10 | 11 | 12 | 13 | 14 | 15 | default 16 | 17 | ::/0 18 | 19 | default 20 | 21 | 22 | 123 23 | default 24 | 25 | ::/0 26 | 27 | default 28 | 29 | 30 | 31 | 32 | 33 | 34 | 3600 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /CLICKHOUSE/Dop_mat/clickhouse-cone_node/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | server_clickhouse: 3 | image: clickhouse/clickhouse-server 4 | container_name: server_clickhouse 5 | ports: 6 | - 8123:8123 7 | restart: unless-stopped 8 | environment: 9 | CLICKHOUSE_USER: ${CLICKHOUSE_USER} 10 | CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD} 11 | CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1 12 | CLICKHOUSE_DB: ${CLICKHOUSE_DB} 13 | volumes: 14 | - './clickhouse/ch_command:/docker-entrypoint-initdb.d/' 15 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Стать автором HalltapeRoadmapDE 2 | 3 | Roadmap – бесплатный агрегатор контента для Data Engineer. 4 | 5 | [Статистика репостов Roadmap в реальном времени](https://tgstat.ru/channel/@halltape_data/478) 6 | 7 | 8 | Он хорошо разлетается в **telegram**, так как люди активно делятся им внутри мессенджера. Чем больше репостов и больше охват, тем дороже и чаще продаете рекламу в своем телеграм канале. 9 | 10 | *** 11 | 12 | ### Как добавить свой контент 13 | 14 | 1. Сделать к себе fork репозитория 15 | 2. Внести необходимые изменения и запушить 16 | 3. Добавить любые ссылки на свои соц сети, бусти и так далее в [таком стиле](GREENPLUM/README.md) 17 | 4. Прожать кнопку Pull Request 18 | 19 | ### Правила контента 20 | 21 | - Старайтесь писать **СРАЗУ КОНКРЕТИКУ**. Истории о вашей жизни, казусные ситуации на работе или моральные вопросы никому не интересны. 22 | Людям надо дать четкие шаги типа **делай РАЗ-ДВА-ТРИ** 23 | 24 | - Сначала ознакомьтесь с тем контентом, который уже есть. Дубликаты не нужны 25 | 26 | - Не рекомендовать 5-10 книг для изучения. Джуны их читать не будут 27 | 28 | - В случае исправления существующего контента, описывать в PR причины исправлений 29 | 30 | 31 | ### Нам нужен контент по этим темам 32 | 33 | Ты можешь выбрать **любую** из этих тем или **предложить свою**. 34 | 35 | - Debezium 36 | - Kafka (теория по аналогии с Greenplum) 37 | - Spark (теория по аналогии с Greenplum) 38 | - Коннекторы к БД (как подключиться к Snowflake, S3, Greenplum, Clickhouse и так далее) 39 | - AI, ChatGPT, AI IDE и прочие современные AI помощники 40 | - Ссылки на полезные ресурсы (Youtube каналы, Сообщества, Телеграм каналы) 41 | - Полезные контакты (менторы, HR) 42 | - Что такое софт скиллы и как их качать? 43 | - Мотивация (как взять себя в руки?) -------------------------------------------------------------------------------- /DBT/images/bereal-2024-10-10-0825.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/DBT/images/bereal-2024-10-10-0825.jpeg -------------------------------------------------------------------------------- /DBT/images/image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/DBT/images/image-1.png -------------------------------------------------------------------------------- /DBT/images/image-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/DBT/images/image-2.png -------------------------------------------------------------------------------- /DBT/images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/DBT/images/image.png -------------------------------------------------------------------------------- /DM/README.md: -------------------------------------------------------------------------------- 1 | # Витрина Данных 2 | 3 |

4 | 5 |

6 | 7 | **Ничего общего с магазином, конечно же, нет!** 8 | 9 | Витрина данных (Data Mart) — это просто таблица или таблицы. Чаще всего DE используют это слово, когда говорят про таблицу для дата аналитиков. Грубо говоря, дата инженеры загрузили данные в хранилище, очистили их от ненужной инфы, обогатили таблицу еще другими таблицами и получили какую-то общую. В ней может быть например собраны все заявки по кредитам, все заявки по ипотекам и кредитным картам в банке за вчерашний день. Хотя на входе там были данные просто с действиями пользователей на сайте. 10 | 11 | Дата инженер раскопал все источники, понял, как с ними работать и сделал для дата аналитика некий готовый срез. 12 | 13 | Витрина данных, аналогично дашборду, позволяет аналитику увидеть агрегированную 14 | информацию в определенном временном или тематическом разрезе, а также 15 | сформировать отчетные данные в виде шаблонизированного документа. Витрина 16 | данных часто представлена в виде денормализованой таблицы, однако это не всегда 17 | удобно и не позволяет решать все задачи, поэтому чаще встречается таблица фактов 18 | и таблица измерений. 19 | 20 | *** 21 | **Таблица фактов** — главная таблица, в которой пишутся события, например, текущие заказы или действия пользователей на сайте. Т.е. некие события, которые скорее всего имеют уникальный характер. 22 | 23 | **Таблица измерений** (англ. dimension table) — таблица, в которой хранятся описания объектов. Например id, ФИО курьера, который доставил заказ. Или данные каждого клиента. Таблицы измерений удобны тем, что там можно хранить те данные, которые не часто меняются. Очевидно, что писать в таблице фактов номер телефона клиента будет избыточно. Нам достаточно один раз его записать в таблицу измерений и дать ссылку на это в таблице фактов. И при любом запросе к определенному заказу, мы всегда получим актуальный номер телефона клиента, потому что мы изменили его в таблице измерений. 24 | *** 25 | 26 | # Модели "Звезда" и "Снежинка" 27 | ## Модель "Звезда" 28 | 29 | Схемы «звезда» и «снежинка» — это два способа структурировать хранилище данных. 30 | 31 | Схема типа «звезда» (пространственная модель, модель измерений и фактов, модель «сущность-связь», dimensional model, star schema) представляется двумя видами таблиц: таблицами фактов и таблицами измерений, которые описывают факты. Схема разбивает таблицу фактов на ряд денормализованных таблиц измерений. Таблица фактов содержит агрегированные данные, которые будут использоваться для составления отчетов, а таблица измерений описывает хранимые данные. Денормализованные проекты менее сложны, потому что данные сгруппированы. Таблица фактов использует только одну ссылку для присоединения к каждой таблице измерений. Более простая конструкция звездообразной схемы значительно упрощает написание сложных запросов. 32 | 33 |

34 | 35 |

36 | 37 | ## Модель "Снежинка" 38 | 39 | Схема типа «снежинка» отличается тем, что использует нормализованные данные. Нормализация означает эффективную организацию данных так, чтобы все зависимости данных были определены, и каждая таблица содержала минимум избыточности. Таким образом, отдельные таблицы измерений разветвляются на отдельные таблицы измерений. Схема «снежинки» использует меньше дискового пространства и лучше сохраняет целостность данных. Основным недостатком является сложность запросов, необходимых для доступа к данным — каждый запрос должен пройти несколько соединений таблиц, чтобы получить соответствующие данные. 40 | 41 |

42 | 43 |

44 | 45 | 46 | *** 47 | ## SCD [Slowly Changing Dimensions] 48 | 49 | > Эта штука очень важна. Обязательно изучите это. 50 | 51 | ### SCD 0 52 | SCD 0 — заключается в том, что данные после первого попадания в таблицу далее никогда не изменяются. Этот метод практически никем не используется, т.к. он не поддерживает версионности. Он нужен лишь как нулевая точка отсчета для методологии SCD. По сути, вообще не SCD. 53 | Таблица, которая хранит пол родственников Дональда Дака - женский, мужской, не определено. Она также не требует ведения истории. 54 | 55 | ### SCD 1 56 | SCD 1 — это обычная перезапись старых данных новыми. В чистом виде этот метод тоже не содержит версионности и используется лишь там, где история фактически не нужна. 57 | 58 | **Пример:** паспортные данные изменились и были перезаписаны 59 | 60 | ### SCD 2 61 | SCD 2 - есть два столбца. Первый столбец с датой, когда запись начала действовать. Вторая дата ставится 9999-01-01. Значит, что строка имеет актуальные данные. При обновлении данных, 9999-01-01 меняется на текущую дату и строка становится уже исторической. При этом новые данные появляются на следующей строке. Смотри пример 62 | 63 | **Пример:** 64 | 65 | | ID | Name | Number | Team | Date_start | Date_end | 66 | |----|---------------|--------|--------|--------------|--------------| 67 | | 1 | Marc Marquez | 93 | Honda | 2013-11-08 | 9999-01-01 | 68 | | 2 | Valentino Rossi | 46 | Yamaha | 2010-11-07 | 9999-01-01 | 69 | | 3 | Dani Pedrosa | 26 | Honda | 2014-11-08 | 2018-01-11 | 70 | | 4 | Jorge Lorenzo | 99 | Ducati | 2017-01-01 | 2019-01-01 | 71 | | 5 | Jorge Lorenzo | 99 | Honda | 2019-01-02 | 9999-01-01 | 72 | 73 | 74 | ### SCD 3 75 | SCD 3 — В самой записи содержатся дополнительные поля для предыдущих значений атрибута. При получении новых данных, старые данные перезаписываются текущими значениями. 76 | 77 | **Пример:** 78 | 79 | | ID | Name | Num | Previous_team | Current_team | Date_start | 80 | |----|---------------|-----|---------------|--------------|--------------| 81 | | 1 | Marc Marquez | 93 | NULL | Honda | 2013-11-08 | 82 | | 2 | Valentino Rossi | 46 | NULL | Yamaha | 2010-11-07 | 83 | | 3 | Dani Pedrosa | 26 | NULL | Honda | 2014-11-08 | 84 | | 4 | Jorge Lorenzo | 99 | Ducati | Honda | 2019-01-02 | 85 | 86 | ### SCD 4 87 | История изменений содержится в отдельной таблице: основная таблица всегда перезаписывается текущими данными с перенесением старых данных в другую таблицу. Обычно этот тип используют для аудита изменений или создания архивных таблиц. 88 | 89 | *** 90 | 91 | > Дальше есть еще 5 и 6 версии, но они являются уже просто комбинациями из выше перечисленных. Шарить за них не нужно. Да и о них мало кто знает вообще. 92 | -------------------------------------------------------------------------------- /DOCKER/README.md: -------------------------------------------------------------------------------- 1 | # Docker 2 | 3 | ## Что такое Docker? 4 | 5 | **Docker** — это платформа, которая позволяет упаковывать приложения и их зависимости в изолированные контейнеры. Это облегчает развертывание и обеспечивает одинаковое поведение приложения в разных средах (локально, на сервере или в облаке). 6 | 7 | ### Преимущества Docker: 8 | - **Портативность:** Работает одинаково на всех системах. 9 | - **Изоляция:** Каждое приложение работает в своём контейнере. 10 | - **Лёгкость:** Контейнеры занимают меньше ресурсов по сравнению с виртуальными машинами. 11 | - **Удобство:** Упрощает управление зависимостями и процессами развертывания. 12 | 13 | [Различие между Docker и Virtual Machine](VM/README.md) 14 | 15 | --- 16 | 17 | ## Что такое Dockerfile? 18 | 19 | **Dockerfile** — это текстовый файл с инструкциями для создания Docker-образа. 20 | 21 | Образ — это шаблон для создания контейнеров. Вы описываете в Dockerfile, какие программы и зависимости нужны вашему приложению, чтобы оно работало. 22 | 23 | ### Пример Dockerfile: 24 | ```Dockerfile 25 | # Используем базовый образ Python 26 | FROM python:3.10-slim 27 | 28 | # Копируем файлы проекта в контейнер 29 | COPY . /app 30 | 31 | # Устанавливаем рабочую директорию 32 | WORKDIR /app 33 | 34 | # Устанавливаем зависимости 35 | RUN pip install -r requirements.txt 36 | 37 | # Запускаем приложение 38 | CMD ["python", "app.py"] 39 | ``` 40 | 41 | 42 | ### Что такое docker-compose? 43 | 44 | docker-compose — это инструмент для запуска нескольких связанных контейнеров. 45 | 46 | Вместо запуска контейнеров вручную, вы описываете их конфигурацию в одном YAML-файле и управляете ими как единой системой. Кстати формат файла пишут, как **.yaml или .yml** (Разницы нет) 47 | 48 | Файлик называют **docker-compose.yaml** 49 | 50 | ```Dockerfile 51 | # Можно собирать из нескольких сервисов 52 | version: "3.6" # Версия формата файла Docker Compose, используемая в данном случае, — `3.6`. 53 | services: 54 | jupyterlab: 55 | image: andreper/jupyterlab:3.0.0-spark-3.0.0 # Образ: `andreper/jupyterlab:3.0.0-spark-3.0.0` 56 | container_name: jupyterlab # Имя контейнера: `jupyterlab` 57 | ports: 58 | - 8888:8888 # 8888:8888 (интерфейс JupyterLab) 59 | - 4040:4040 # 4040:4040 (интерфейс Spark UI) 60 | volumes: 61 | - ./build/workspace:/opt/workspace # Слева папка у вас на компе, а справа папка внутри контейнера. Все, что положишь в папку workspace, будет автоматически и внутри контейнера! 62 | spark-master: 63 | image: andreper/spark-master:3.0.0 64 | container_name: spark-master 65 | ports: 66 | - 8080:8080 67 | - 7077:7077 68 | volumes: 69 | - ./build/workspace:/opt/workspace 70 | spark-worker-1: 71 | image: andreper/spark-worker:3.0.0 72 | container_name: spark-worker-1 73 | environment: 74 | - SPARK_WORKER_CORES=2 75 | - SPARK_WORKER_MEMORY=2g 76 | ports: 77 | - 8081:8081 78 | volumes: 79 | - ./build/workspace:/opt/workspace 80 | depends_on: 81 | - spark-master # Зависит от сервиса spark-master, чтобы гарантировать его запуск после мастера. 82 | 83 | ``` 84 | 85 | **Для запуска:** 86 | Этой командой можно запустить сборку и запуск docker-контейнера в фоновом режиме (в терминале не будут отображаться логи) 87 | ```Dockerfile 88 | docker-compose up -d 89 | ``` 90 | 91 | Пример docker-compose взят [отсюда](https://github.com/halltape/HalltapeSparkCluster) 92 | 93 | 94 | ## Распространённые команды Docker 95 | 96 | ### Управление образами 97 | - **`docker build -t <имя_образа> .`** 98 | Собирает образ из Dockerfile в текущей директории. 99 | - **`docker images`** 100 | Показывает список всех образов на вашем компьютере. 101 | - **`docker rmi `** 102 | Удаляет образ по его идентификатору. 103 | 104 | ### Управление контейнерами 105 | - **`docker ps`** 106 | Показывает запущенные контейнеры. 107 | - **`docker ps -a`** 108 | Показывает все контейнеры, включая остановленные. 109 | - **`docker stop `** 110 | Останавливает запущенный контейнер. 111 | - **`docker rm `** 112 | Удаляет остановленный контейнер. 113 | 114 | ### Просмотр логов 115 | - **`docker logs `** 116 | Показывает логи контейнера. -------------------------------------------------------------------------------- /DOCKER/VM/README.md: -------------------------------------------------------------------------------- 1 | # Разница между Virtual Machine (VM) и Docker 2 | 3 | ## 1. Что такое Virtual Machine (VM)? 4 | Virtual Machine (виртуальная машина) — это эмулированная компьютерная система, которая полностью имитирует физический компьютер, включая операционную систему, ресурсы и приложения. VM запускается поверх гипервизора (например, VMware, Hyper-V, VirtualBox), который управляет виртуализацией. 5 | 6 | ### Преимущества VM: 7 | - Полная изоляция: каждая VM имеет свою ОС и не зависит от других VMs. 8 | - Поддержка разных ОС: можно запускать Linux на Windows или наоборот. 9 | - Подходит для запуска приложений с уникальными требованиями к среде. 10 | 11 | ### Недостатки VM: 12 | - Затраты на ресурсы: каждая VM включает свою ОС, что занимает много памяти и CPU. 13 | - Медленный запуск: требует больше времени на инициализацию ОС. 14 | 15 | --- 16 | 17 | ## 2. Что такое Docker? 18 | Docker — это платформа для контейнеризации, которая позволяет изолировать приложения и их зависимости в лёгких **контейнерах**, работающих поверх единого ядра хостовой операционной системы. 19 | 20 | ### Преимущества Docker: 21 | - Лёгкость: контейнеры делят ядро ОС, что снижает затраты на ресурсы. 22 | - Быстрый запуск: контейнеры запускаются за секунды. 23 | - Портативность: контейнеры работают одинаково на любом хосте с Docker. 24 | - Простота управления зависимостями: всё, что нужно для приложения, включено в контейнер. 25 | 26 | ### Недостатки Docker: 27 | - Ограниченная изоляция: контейнеры зависят от ядра хостовой ОС (например, нельзя запустить контейнер с Windows на Linux-хосте). 28 | - Сложность управления в крупных проектах: требует дополнительных инструментов для оркестрации (например, Kubernetes). 29 | 30 | --- 31 | 32 | ## 3. Ключевые отличия 33 | 34 | | Характеристика | Virtual Machine (VM) | Docker | 35 | |-----------------------------|-----------------------------------------------------|------------------------------------------------| 36 | | **Изоляция** | Полная (каждая VM имеет собственное ядро ОС). | Лёгкая (контейнеры делят ядро хостовой ОС). | 37 | | **Размер** | Большой (гигабайты, т.к. включена ОС). | Маленький (мегабайты, т.к. ядро не копируется).| 38 | | **Запуск** | Медленный (минуты на инициализацию ОС). | Быстрый (секунды для старта контейнера). | 39 | | **Ресурсы** | Требует больше памяти и CPU. | Эффективнее использует ресурсы. | 40 | | **Совместимость** | Можно запускать разные ОС. | ОС контейнера должна соответствовать ядру хоста. | 41 | | **Использование** | Подходит для сложных, изолированных окружений. | Удобно для разработки, тестирования, CI/CD. | 42 | 43 | --- 44 | 45 | ## 4. Пример наглядного сравнения 46 | 47 | ### Virtual Machine: 48 | - Устанавливаете Linux на Windows через VMware. 49 | - Каждый VM включает: 50 | - Полную ОС. 51 | - Свои ресурсы (CPU, RAM, диск). 52 | - Если нужно 5 приложений, каждая VM может весить по 2–4 ГБ. 53 | 54 | ### Docker: 55 | - Запускаете 5 приложений в контейнерах. 56 | - Все контейнеры используют одно ядро ОС хоста. 57 | - Вес контейнеров — 100–200 МБ каждый. 58 | 59 | --- 60 | 61 | ## 5. Выводы 62 | - **Выбирайте VM**, если: 63 | Вам нужна полная изоляция, или вы работаете с приложениями, требующими разных операционных систем. 64 | 65 | - **Выбирайте Docker**, если: 66 | Вы хотите быстро разрабатывать и развёртывать приложения с минимальными затратами на ресурсы. 67 | 68 | Docker не заменяет виртуальные машины, но дополняет их, предоставляя лёгкие и эффективные инструменты для контейнеризации приложений. -------------------------------------------------------------------------------- /DWH/Additional_information/ACID/README.md: -------------------------------------------------------------------------------- 1 | ## Куратор раздела 2 | 3 | 4 | 5 | **Шустиков Владимир**, оставивший военную жизнь позади и ушедший в данные с головой. Работаю с данными более 2х лет и останавливаться не собираюсь! Веду: 6 | 7 | [Telegram канал](https://t.me/Shust_DE) 8 | 9 | [Youtube канал](https://www.youtube.com/@shust_de) 10 | 11 | Если хочешь сменить текущую профессию на Дата Инженера — пиши не стесняйся, я сам проходил этот не легкий путь и тебе помогу https://t.me/ShustDE. 12 | 13 | Хочешь улучшить текущий раздел, внести недостающее или поправить формулировку? Предлагай PR и тегай [@ShustGF](https://github.com/ShustGF). 14 | 15 | # ACID 16 | 17 | Простое опрепределение: 18 | 19 | **Транзакция** — последовательность команд, которая удовлетворяет требованием ACID. 20 | 21 | Развёрнутое определение: 22 | 23 | **Транзакция** — последовательность команд, которая сохраняет согласованность базы данных при условии, что транзакция выполняется полностью и без помех со стороны других транзакций. 24 | 25 | **ACID** — это аббревиатура состоящая из 4 компонентов: 26 | 27 | * Атомарность 28 | * Согласованность 29 | * Долговечность 30 | * Изоляция 31 | 32 | ## Атомарность 33 | 34 | Атомарность — это свойство, которое гарантирует, что каждая транзакция будет выполнена полностью, либо не будет выполнена совсем. 35 | 36 | ## Согласованность 37 | 38 | Согласованность, подразумевает, что каждая выполненная транзакция переводит БД из одного согласованного состояния к следующему согласованному состоянию 39 | 40 | ## Долговечность 41 | 42 | Долговечность означает сохранность данных, даже после сбоя системы. 43 | 44 | ## Изоляция 45 | 46 | Изоляция, подразумевает собой, что одновременные транзакции не будут влиять друг на друга. 47 | 48 | # Виды изоляции 49 | 50 | Согласно стандарта SQL, транзакции имеют 4 уровня изоляции и каждая из них блокирует определённые возникающие аномалии. Все виды представлены в таблице. 51 | 52 | | Параметр | Предотвращаемые аномалии | 53 | |-----------------------------------|------------------------------------| 54 | | **READ UNCOMMITTED** | «потерянных обновлений» | 55 | | **READ COMMITTED** | «потерянных обновлений», «грязного чтения» | 56 | | **REPEATABLE READ** | «потерянных обновлений», «грязного чтения», «не повторяющего чтения», «фантомного чтения»| 57 | | **SERIALIZABLE** | предотвращает любые аномалии | 58 | 59 | Теперь пройдемся по каждому виду и посмотрим от каких аномалий они предотвращают. 60 | 61 | # Аномалиии 62 | 63 | ## Аномалия "потерянных обновлений" 64 | 65 | Аномалия **потерянных обновлений** подразумевает, что первая транзакция может изменить данные, запущенные после неё транзакций. 66 | 67 | Пример: 68 | 69 |

70 | Аномалия потерянных обновлений 71 |

72 | 73 | Есть 2 клиента, и 1й клиент запускает транзакцию на изменение данных, во время выполнения данной транзакции 2й клиент запускает еще одну транзакцию, которая заканчивает выполнение до окончания транзакции клиента 1, после чего заканчивается транзакция 1го клиента. Как мы видим из рисунка значения изменены на основе транзакции 1, а транзакция 2 полностью перезаписана. 74 | 75 | ## Аномалия "грязного чтения" 76 | 77 | Под **грязным чтением** понимается ситуация, когда запрос видит незафиксированные изменения других транзакций. 78 | 79 | Пример: 80 | 81 |

82 | Аномалия грязного чтения 83 |

84 | 85 | Первый пользователь запускает транзакцию на изменение данных, 2й считывает данные первый раз и видит еще не измененные данные, после этого ждет 2 секунды, во время этих 2х секунд 1й доходит до изменения 100го идентификатора и продолжает выполнение транзакции, после этого 2й еще раз считывает данные и видит, что данные изменились, хотя транзакция 1го еще не завершена. 86 | 87 | ## Аномалия "не повторяющего чтения" 88 | 89 | Аномалия **не повторяющего чтения**, это когда повторное чтение строки вернет другое значение, если оно было изменено и зафиксировано другой транзакцией. 90 | 91 | Пример: 92 | 93 |

94 | Аномалия не повторяющего чтения 95 |

96 | 97 | Второй пользователь начинает читать данные и получает определённое значение выборки, после у него запускается задержка на 20 секунд, в это время 1 клиент, изменяет значения в таблице, затрагивающее значение 2го клиента, и заканчивает транзакцию, после этого 2й пользователь еще раз считывает этот же запрос и получает совсем другую выборку. 98 | 99 | ## Аномалия "фантомного чтения" 100 | 101 | Аномалия **фантомного чтения**, это когда повторный запрос по одному и тому же условию вернет другую выборку, если другая транзакция добавила и зафиксировала новые строки, удовлетворяющие этому условию. 102 | 103 | Пример: 104 | 105 |

106 | Аномалия фантомного чтения 107 |

108 | 109 | Второй клиент начинает считывать данные и ожидает 20 секунд. А это время 1й клиент вносит новые данные в таблицу и заканчивает транзакцию. После ожидания 2й клиент еще раз считывает данные и получает совсем другой ответ, так как в его ответ попали новые строки. 110 | -------------------------------------------------------------------------------- /GREENPLUM/CASES_OPTIMIZATION/README.md: -------------------------------------------------------------------------------- 1 | ## Куратор раздела 2 | 3 | 4 | 5 | **Шустиков Владимир**, оставивший военную жизнь позади и ушедший в данные с головой. Работаю с данными более 2х лет и останавливаться не собираюсь! Веду: 6 | 7 | [Telegram канал](https://t.me/Shust_DE) 8 | 9 | [Youtube канал](https://www.youtube.com/@shust_de) 10 | 11 | Если хочешь сменить текущую профессию на Дата Инженера — пиши не стесняйся, я сам проходил этот не легкий путь и тебе помогу https://t.me/ShustDE 12 | 13 | Хочешь улучшить текущий раздел, внести недостающее или поправить формулировку? Предлагай PR и тегай [@ShustGF](https://github.com/ShustGF). 14 | 15 | ## Кейс 1: Уходи от OR в JOIN'ах 16 | 17 | Есть запрос в котором втречается JOIN с 3мя условиями. Таблицы имеют большое кол-во строк. 18 | 19 | ```sql 20 | SELECT ... 21 | FROM _tmp_calc_cred AS cc 22 | INNER JOIN _postback_api as pa 23 | ON cc.request_external_id = pa.EXTERNAL_ID OR 24 | cc.calculation_id = pa.EXTERNAL_ID OR 25 | cc.request_id = pa.EXTERNAL_ID 26 | ``` 27 | 28 | Во первых в данном случе стоит рапледелить таблицу `_tmp_calc_cred` по всем сегментам, так как в JOIN используется 3 разные колонки, а таблицу `_postback_api` по ключу `EXTERNAL_ID`, чтобы запрос выполнялся параллельно на разных сегментах. 29 | 30 | Данный запрос стоит преобразовать к следующиму виду: 31 | 32 | ```sql 33 | select ... 34 | FROM alexd._tmp_CALCULATION_CREDIT AS cc 35 | INNER JOIN alexd._postback_api as pa 36 | ON cc.request_external_id = pa.EXTERNAL_ID 37 | union all 38 | select ... 39 | FROM alexd._tmp_CALCULATION_CREDIT AS cc 40 | INNER JOIN alexd._postback_api as pa 41 | ON cc.calculation_id = pa.EXTERNAL_ID 42 | union 43 | select ... 44 | FROM alexd._tmp_CALCULATION_CREDIT AS cc 45 | INNER JOIN alexd._postback_api as pa 46 | ON cc.request_id = pa.EXTERNAL_ID 47 | ``` 48 | 49 | В первом случае выберится физический вид JOIN'а - `Nested Loop`, 2й запрос хоть и больше, но выберится `Hash JOIN`. Здесь главное по отдельности запустить запросы и пприкинуть, какое максимальное кол-во строк может получиться в результате. Если строк в результате получается больше, чем в самих таблицах (произошел CROSS JOIN данных), то возможно 1й вариант будет выстрее! 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Git/README.md: -------------------------------------------------------------------------------- 1 | # Как подключиться к Github? 2 | 3 | **Github** - это обычный сайт, где каждый может загрузить туда cвой код или скачать его оттуда. Есть репозитории (на "земном" папки ), в которых и хранится вся информация. Ниже инструкция, как работать с **github**. 4 | 5 | ***С гитом можно работать, как через Terminal, так и через VSCode или другую IDE (последнее проще).*** 6 | * * * 7 | ### Работа через Terminal (Mac) или PowerShell (Win): 8 | 9 | Сначала подключимся к Github через terminal. Для этого нам нужно создать ключ (ссылку), который свяжет наш компьютер с Github. Заходим в terminal или командную строку. Пишем: 10 | 11 | **Создаем ssh-keygen** 12 | > ssh-keygen 13 | - Нажимаем везде **Enter**. В моем случае пришлось еще 14 | нажать **y** в **Overwrite (y/n)?** и пересоздать ключ, так как он у меня уже был 15 | ```bash 16 | (base) halltape@Evgeniis-MacBook-Pro ~ % ssh-keygen 17 | Generating public/private rsa key pair. 18 | Enter file in which to save the key (/Users/halltape/.ssh/id_rsa): 19 | /Users/halltape/.ssh/id_rsa already exists. 20 | Overwrite (y/n)? y 21 | Enter passphrase (empty for no passphrase):  22 | Enter same passphrase again:  23 | Your identification has been saved in /Users/halltape/.ssh/id_rsa 24 | Your public key has been saved in /Users/halltape/.ssh/id_rsa.pub 25 | The key fingerprint is: 26 | SHA256:vBzK7g4/3zcA3wUb9HLpoaCHLudJ1qsaXg12J9bchaI halltape@Evgeniis-MacBook-Pro.local 27 | The key's randomart image is: 28 | +---[RSA 3072]----+ 29 | |           ..    | 30 | |            o. o | 31 | |          . o+* .| 32 | |       ..o =.B.o | 33 | |        SoE.=.o  | 34 | |     . = Xoo.    | 35 | |    . = O o.     | 36 | |     =.O o .o    | 37 | |     oB+=.o. .   | 38 | +----[SHA256]-----+ 39 | ``` 40 | 41 | Дальше нам нужно открыть файл, где создался этот ключ (просто шифр из **многобукв**). 42 | **Username** у вас свой! 43 | 44 | **Показать ssh-keygen** 45 | > cat /Users/username/.ssh/id_rsa.pub 46 | - Копируем все, начиная от ssh-rsa до local 47 | ```bash 48 | (base) halltape@Evgeniis-MacBook-Pro ~ % cat /Users/halltape/.ssh/id_rsa.pub 49 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRQ 50 | KSox2pVCd/TOrSPGojUoIqL2flV0vII6seQ1xC3T 51 | eokWlpYRbvPFS9KsSW+mEmsALWlmhNfaFBRfRsifgjCt 52 | rFBHWwwYkeWJiOmo9fxpCBf7wi4reg8458634hjge804 53 | NOvUQ11XXGBlw2nA4Vgal1adGgMXptQQzQ4taq3pHTBNoFFARLSA 54 | /vNkgXtfnXvBGlDj3YQNVbM8IViWkwR 55 | rtKLjvVVVUpXct3TSFpK1eGGxGB/b1KDV+HeCOOKPi9j8=hallta 56 | pe@Evgeniis-MacBook-Pro.local 57 | (base) halltape@Evgeniis-MacBook-Pro ~ % 58 | ``` 59 | 60 | * * * 61 | ### Подключим свой Github с помощью SSH 62 | Заходим в настройки **SSH and GPG keys**. Нажимаем New SSH key 63 | 64 | ![ssh](../png/git_ssh.png) 65 | 66 | **Вставляем скопированный ssh-keygen** 67 | 68 | ![ssh2](../png/git_ssh2.png) 69 | ![ssh3](../png/git_ssh3.png) 70 | 71 | Супер! Теперь мы можем скачивать все, что угодно с GitHub! 72 | 73 | *** 74 | Но прежде, чем скачать репозиторий к себе на ПК, следует сделать его копию у себя на Github. Это будет лично ваша копия, с которой вы можете делать все что угодно (изменять, удалять, добавлять и т.д.) 75 | 76 | ![fork](../png/git_fork.png) 77 | * * * 78 | ### В terminal (командная строка) заходим в папку, куда мы хотим скачать наш репозиторий 79 | 80 | **Команда *pwd* покажет место, где мы находимся** 81 | > pwd 82 | ```bash 83 | (base) halltape@Evgeniis-MacBook-Pro Desktop % pwd 84 | /Users/halltape/Desktop 85 | ``` 86 | **Посмотреть содержимое папки** 87 | > ls 88 | ```bash(base) 89 | halltape@Evgeniis-MacBook-Pro ~ % ls 90 | Applications Downloads 91 | Public Creative Cloud 92 | Files Library PycharmProjects 93 | DataGripProjects Movies miniconda3 Desktop 94 | Music mysql Documents Pictures 95 | ``` 96 | 97 | **Зайдите в место, куда вам будет удобно скачать репозиторий 98 | Команда *cd* переместит вас в папку** 99 | 100 | *Допустим мы здесь Users/halltape/Desktop* 101 | > cd .. 102 | > 103 | > cd Downloads 104 | - В первом случае мы перемещаемся на папку выше, в папку **halltape** 105 | - Во втором случае мы перемещаемся в папку **Downloads** (можно писать любую папку в рамках тех папок, которые есть) 106 | 107 | **Установка Git** 108 | 109 | Чтобы работать с Git, нужно его установить [вот так на Mac](https://git-scm.com/downloads/mac) или [вот так на Win](https://git-scm.com/downloads/win) 110 | 111 | >git нужен, чтобы вы могли скачивать и загружать свой код со своего компьютера на GitHub и обратно, а также отслеживать версии кода, но об этом чуть позже. 112 | > 113 | *** 114 | **А теперь зайдите [сюда](https://github.com/halltape/HalltapeRoadmapDE).** 115 | 116 | Этот репозиторий вы должны будете скачать к себе на ПК по инструкции ниже. 117 | 118 | **Копируем ссылку на репозиторий** 119 | 120 | ![fork2](../png/git_fork2.png) 121 | 122 | **Команда ниже начнет скачивание репозитория с github в то место, 123 | где вы находитесь, согласно terminal.** 124 | **Скачать репозиторий к себе на ПК** 125 | > git clone ```git@github.com:halltape/data-engineering.git``` 126 | 127 | - Мы скачали репозиторий к себе на ПК. Теперь у нас есть копия этой папки на компьютере. Мы можем вносить любые изменения (удалять, добавлять или править файлы в этом репозитории). Например, мы сделали домашнее задание и хотим загрузить его обратно в свой **github**. Но нам **НЕ НУЖНО** снова грузить **ЦЕЛЫЙ РЕПОЗИТОРИЙ** обратно. Нам достаточно обновить одну или несколько папок (файлов). 128 | - Для этого есть 4 команды: **git status, git add, git commit, git push** 129 | 130 | **Посмотреть список новых или обновленных файлов на нашем ПК** 131 | > git status 132 | 133 | - Нам покажут все новые или обновленные файлы и папки, которые появились на нашем компьютере в скачанном репозитории. Он как бы отслеживает изменения. 134 | 135 | **Например я внес изменения и добавил файл HALLTAPE.txt** 136 | > git status 137 | - Как видно, terminal сразу показал, что есть **modified: HALLTAPE.txt** 138 | ```bash 139 | (base) halltape@Evgeniis-MacBook-Pro data-engineering % git status 140 | On branch develop 141 | Your branch is up to date with 'origin/develop'. 142 | 143 | Changes not staged for commit: 144 | (use "git add ..." to update what will be committed) 145 | (use "git restore ..." to discard changes in working directory) 146 | 'modified: HALLTAPE.txt' 147 | 148 | no changes added to commit (use "git add" and/or "git commit -a") 149 | (base) halltape@Evgeniis-MacBook-Pro data-engineering % 150 | ``` 151 | 152 | **Добавить в список на загрузку файлы, которые нам показали при git status** 153 | > git add . 154 | > 155 | > git add HALLTAPE.txt 156 | 157 | - **git add .** - Точка здесь обязательна! Добавь все, что появилось новенького и удали то, что было удалено. Грубо говоря, мы соглашаемся со **ВСЕМИ** изминениями в репозитории. 158 | - **git add HALLTAPE.txt** - Добавь только файл HALLTAPE.txt (можно написать название файлов через пробел. Тогда добавятся несколько) 159 | 160 | **Команда добавляет комментарий к загрузке.** 161 | > git commit -m 'homework_01' 162 | 163 | - Комментарий будет отображаться на **github**, когда мы все загрузим. Можно писать что угодно 'yo_iam_rapper'. Это удобно для вас, чтобы вы понимали, что вы там меняли например. 164 | 165 | **НЕ ГРУЗИ НА ВЕТКУ **MASTER**!** 166 | > git checkout -b develop 167 | > 168 | > git switch develop 169 | - Создай ветку develop. И далее переключись на нее. На ветке master должен храниться исходник. Сейчас это не так важно, но лучше привыкнуть к этому сразу 170 | ```bash 171 | (base) halltape@Evgeniis-MacBook-Pro DATA % git checkout -b develop 172 | ``` 173 | 174 | **Проверь на какой ты ветке** 175 | > git branch 176 | - Команда покажет, на какой ветке ты сейчас находишься 177 | ```bash 178 | (base) halltape@Evgeniis-MacBook-Pro DATA % git branch 179 | *develop 180 | master 181 | ``` 182 | **Загрузить!** 183 | > git push origin develop 184 | - Эта команда загружает все выбранные вами файлы на ветку develop. Все! 185 | 186 | 187 | *** 188 | **Полезные ссылки** 189 | 190 | ➜ [9 Git Команд на 99% Случаев Жизни](https://www.youtube.com/watch?v=XuFaQSW79rM) -------------------------------------------------------------------------------- /HADOOP/ECOSYSTEM_HADOOP/README.md: -------------------------------------------------------------------------------- 1 | ## Куратор раздела 2 | 3 | 4 | 5 | **Подвальный Артем**, 6 | _Data Engineer/Data Scientist_ 7 | 8 | [Канал Data Engineer Lab](https://t.me/dataengineerlab) 9 | 10 | Хочешь перейти в дата-инженерию, но не знаешь с чего начать? Пиши - составим резюме, продумаем твое развитие [https://t.me/ampodvalniy](https://t.me/ampodvalniy) 11 | 12 | Хочешь улучшить текущий раздел, внести недостающее или поправить формулировку? Предлагай PR и тегай [@Artemlin6231](https://github.com/Artemlin6231) 13 | 14 | ## Немного об этой главе 15 | Экосистема hadoop разворачивается в большей части компаний при работе с BigData и знание её компонентов также важно как и самого HDFS. 16 | 17 | Приятного изучения) 18 | 19 | 20 | 21 | 22 | ## Компоненты экосистемы Hadoop 23 | 24 | 25 |

26 | map_reduce 27 |

28 | 29 | ### HDFS (Hadoop Distributed File System) 30 | Распределённая файловая система, обеспечивающая надёжное и масштабируемое хранение больших объёмов данных на кластере из обычных серверов. 31 | 32 | ### YARN (Yet Another Resource Negotiator) 33 | Слой управления ресурсами и планирования заданий. Позволяет эффективно распределять ресурсы между различными приложениями, такими как MapReduce, Spark, Tez и другими. 34 | 35 | ### MapReduce и Spark 36 | Движки для распределённой обработки данных: 37 | - **MapReduce** — классическая модель обработки больших данных. 38 | - **Spark** — более современный, быстрый и гибкий фреймворк для распределённых вычислений в памяти. 39 | 40 | ### Дополнительные инструменты 41 | - **Hive** — SQL-подобный интерфейс для анализа данных в Hadoop. 42 | - **Pig** — язык потоков данных, простой в использовании для анализа. 43 | - **HBase** — распределённая колонко-ориентированная база данных. 44 | - **Oozie** — планировщик рабочих процессов (workflow scheduler). 45 | - **ZooKeeper** — служба координации и управления распределёнными приложениями. 46 | 47 | --- 48 | 49 | ## MapReduce 50 | 51 | ### Зачем нужен MapReduce? 52 | 53 | В условиях стремительного роста объёмов информации традиционные методы обработки данных перестали справляться с поставленными задачами. Компании столкнулись с необходимостью обрабатывать терабайты и даже петабайты данных ежедневно. Именно в ответ на этот вызов и появился MapReduce — революционный подход, ставший фундаментом для распределённых вычислений в рамках экосистемы Hadoop. 54 | 55 | ### Как работает MapReduce? 56 | 57 |

58 | map_reduce 59 |

60 | 61 | MapReduce — это способ обработки больших объёмов данных за счёт разбиения задачи на мелкие подзадачи, которые параллельно обрабатываются на разных машинах в кластере. 62 | 63 | #### Этапы обработки: 64 | 65 | 1. **Input** 66 | На вход подаётся большой массив данных: текст, логи, последовательности ДНК и т.д. 67 | 2. **Splitting** 68 | Данные делятся на фрагменты, которые обрабатываются независимо. 69 | 3. **Mapping** 70 | Каждый фрагмент проходит через функцию `map`, которая превращает данные в пары «ключ — значение». 71 | 4. **Shuffling** 72 | Все одинаковые ключи группируются: 73 | 5. **Reducing** 74 | К каждой группе применяется функция `reduce`, которая агрегирует значения. 75 | 6. **Result** 76 | Формирование окончательного результата 77 | 78 | --- 79 | 80 | ## Что было до YARN? 81 | 82 | До появления YARN, архитектура Hadoop в версии **1.x** была построена вокруг модели, в которой система обработки данных была тесно связана с системой управления ресурсами. Центральную роль в этой архитектуре играл компонент под названием **JobTracker**, а на каждом узле кластера работал агент **TaskTracker**. 83 | 84 | **JobTracker** размещался на одном выделенном узле и выполнял сразу несколько функций: принимал задания от клиентов (в формате MapReduce), разбивал их на задачи, распределял задачи между узлами, контролировал выполнение и восстанавливал задачи при сбоях. Таким образом, он одновременно был и координатором выполнения, и диспетчером ресурсов, что со временем приводило к чрезмерной нагрузке на него — особенно в крупных кластерах. 85 | 86 | **TaskTracker**, в свою очередь, запускался на каждом рабочем узле и исполнял задачи, полученные от JobTracker. Он периодически отправлял отчёты о статусе выполнения задач. При этом каждый TaskTracker имел фиксированное число слотов для `map` и `reduce` задач (например, по два каждого типа). Такая статическая настройка означала, что если задачи одного типа отсутствовали, то ресурсы слота простаивали, что снижало эффективность использования кластера. 87 | 88 | К тому же, масштабируемость была сильно ограничена: JobTracker хранил в оперативной памяти всю информацию обо всех заданиях и задачах в кластере. При большом числе заданий он становился узким местом, начинал "захлёбываться" и мог выйти из строя. Поскольку он был **единственной точкой отказа**, его сбой останавливал всю работу кластера. 89 | 90 | --- 91 | 92 | ## Что такое YARN? 93 | 94 | В ответ на эти архитектурные ограничения в версии **Hadoop 2.x** появилась новая система управления ресурсами — **YARN (Yet Another Resource Negotiator)**. Она стала кардинальной реформой, позволившей отделить управление ресурсами от логики выполнения приложений, что обеспечило гибкость, отказоустойчивость и расширяемость всей экосистемы Hadoop. 95 | 96 | Благодаря YARN, Hadoop больше не ограничен только MapReduce-программами — теперь на одном кластере могут параллельно работать Spark, Hive, Tez, Flink и многие другие фреймворки. Это позволило превратить Hadoop из специализированного инструмента в универсальную платформу для обработки больших данных. 97 | 98 |

99 | yarn 100 |

101 | 102 | --- 103 | 104 | ## Архитектура YARN в Hadoop 2.x 105 | 106 | Для решения проблем предыдущей версии в **Hadoop 2.x** была представлена новая архитектура — **YARN (Yet Another Resource Negotiator)**. Она стала ключевым компонентом, кардинально изменившим подход к управлению ресурсами в распределённой среде. 107 | 108 | Основная идея YARN — **разделить управление ресурсами и выполнение приложений**, тем самым сделав систему более гибкой, масштабируемой и пригодной для работы с разными типами вычислений, а не только с MapReduce. 109 | 110 | ### Основные компоненты YARN: 111 | 112 | - **ResourceManager** 113 | Центральный управляющий компонент, выполняющий роль глобального диспетчера ресурсов кластера. Он принимает заявки на ресурсы от приложений, распределяет ресурсы между ними и следит за состоянием узлов. При этом **ResourceManager не управляет задачами напрямую**. 114 | 115 | - **ApplicationMaster** 116 | Это уникальный процесс, который запускается отдельно для каждого приложения (например, Spark, Hive, MapReduce и др.). Он отвечает за: 117 | - организацию выполнения приложения, 118 | - переговоры с ResourceManager по поводу выделения ресурсов, 119 | - управление задачами внутри приложения. 120 | Такой подход позволяет запускать **разные приложения параллельно**, независимо друг от друга. 121 | 122 | - **NodeManager** 123 | Агент, работающий на каждом узле кластера. Он: 124 | - отслеживает локальные ресурсы (CPU, память, диск и т.д.), 125 | - отправляет отчёты ResourceManager'у, 126 | - запускает **контейнеры (containers)** — изолированные среды выполнения задач. 127 | 128 | - **Container** 129 | Это изолированная среда, в которой выполняются задачи приложения — будь то MapReduce, Spark, или любой другой фреймворк. Контейнеры запускаются и управляются NodeManager'ом. 130 | 131 | --- 132 | 133 | ### Зачем это всё? 134 | 135 | Благодаря этой архитектуре, YARN предоставляет **универсальный и расширяемый слой управления ресурсами**, который может обслуживать не только MapReduce-приложения, но и любые другие распределённые фреймворки. Это позволило: 136 | 137 | - эффективно использовать ресурсы кластера, 138 | - масштабировать системы до тысяч узлов и миллионов задач, 139 | - запускать разнообразные типы вычислений — от пакетной до потоковой обработки и ML-задач. 140 | 141 | --- 142 | 143 | ### Результат 144 | 145 | Благодаря YARN, Hadoop превратился из специализированной MapReduce-платформы в **универсальную систему обработки больших данных**, поддерживающую: 146 | 147 | - Spark и другие in-memory вычисления, 148 | - потоковую обработку(spark streaming), 149 | - SQL-запросы и интерактивные аналитические задачи (Hive, Presto), 150 | - интеграцию с ML-фреймворками. 151 | 152 | ## Типичные вопросы на собеседовании 153 | 1. Как YARN распределяет ресурсы? 154 | 2. Как работает MapReduce — опишите все этапы? 155 | 3. Зачем нужен shuffle и почему он дорогой по ресурсам? 156 | 4. Чем Spark отличается от MapReduce? 157 | 5. Где работает MapReduce? (в памяти или на диске)? 158 | -------------------------------------------------------------------------------- /HADOOP/README.md: -------------------------------------------------------------------------------- 1 | ## Куратор раздела 2 | 3 | 4 | 5 | **Подвальный Артем**, 6 | _Data Engineer/Data Scientist_ 7 | 8 | [Канал Data Engineer Lab](https://t.me/dataengineerlab) 9 | 10 | Хочешь перейти в дата-инженерию, но не знаешь с чего начать? Пиши - составим резюме, продумаем твое развитие [https://t.me/ampodvalniy](https://t.me/ampodvalniy) 11 | 12 | 13 | Хочешь улучшить текущий раздел, внести недостающее или поправить формулировку? Предлагай PR и тегай [@Artemlin6231](https://github.com/Artemlin6231) 14 | 15 | ## Немного об этой главе 16 | Понимание Hadoop Distributed File System - одна из наиболее часто встречающихся тем на собеседованиях, так что разбираться в ней стоит каждому Дата-инженеру. 17 | 18 | Приятного изучения) 19 | 20 | 21 | # Hadoop 22 | 23 | **Hadoop Distributed File System** — это один из фундаментальных компонентов в экосистеме обработки больших данных. Он стал краеугольным камнем для дата-инженеров по всему миру и используется в самых разных системах: от банков и телекома до стриминговых платформ и дата-центров. 24 | 25 | ## Почему HDFS стал таким важным: 26 | 27 | - Распределённое хранение данных: большие файлы разбиваются на блоки и автоматически распределяются по множеству узлов. 28 | - Отказоустойчивость: благодаря репликации блоков (по умолчанию 3 копии), данные не теряются при сбоях узлов. 29 | - Масштабируемость: можно начинать с нескольких серверов и масштабироваться до тысяч машин без изменения архитектуры. 30 | - Параллельная обработка: HDFS идеально сочетается с фреймворками типа MapReduce, позволяя выполнять анализ "на месте", рядом с данными. 31 | - Ориентирован на потоковую запись: файлы в HDFS пишутся один раз и читаются много раз — это идеально для аналитических систем. 32 | 33 | --- 34 | 35 | ## Архитектура HDFS: 36 |

37 | hadoop 38 |

39 | 40 | ### Основные компоненты системы 41 | 42 | #### Client (Клиент) 43 | 44 | Клиент — это пользователь или приложение, взаимодействующее с HDFS. Он не пересылает данные через управляющий узел (NameNode), а напрямую обменивается ими с узлами хранения — DataNode. Однако, перед этим клиент обращается к NameNode для получения информации о размещении данных. 45 | 46 | #### NameNode 47 | 48 | NameNode — главный управляющий узел системы. Он хранит метаинформацию, такую как структура каталогов, имена файлов, расположение блоков, права доступа и другую служебную информацию. Самих данных на NameNode нет — только информация об их размещении. Все операции по чтению и записи начинаются с запроса клиента к NameNode. 49 | 50 | #### DataNode 51 | 52 | DataNode — рабочие узлы, на которых физически размещаются блоки данных. Каждый файл в HDFS разбивается на блоки (обычно по 128 или 256 МБ), которые затем распределяются между несколькими DataNode. Эти узлы обрабатывают запросы клиента на чтение и запись блоков, а также участвуют в процессе репликации. 53 | 54 | --- 55 | 56 | ## Особенности HDFS 57 | 58 | В отличие от традиционных файловых систем, HDFS поддерживает только однократную последовательную запись: файл можно записать только один раз и только одним процессом. Это связано с тем, что система ориентирована на хранение и обработку очень крупных файлов (чаще всего больше 10 ГБ). Каждый файл разбивается на крупные блоки — по умолчанию 128 МБ, но можно увеличить до 256 МБ. Эти блоки представляют собой бинарные объекты (BLOB), физически размещённые на DataNode. 59 | 60 | --- 61 | 62 | ## Поддерживаемые операции в HDFS 63 | 64 | HDFS поддерживает базовый набор операций для работы с файлами в распределённой среде. Это включает запись новых данных, чтение существующих файлов, удаление ненужной информации, а также автоматическую репликацию данных для обеспечения надёжности и отказоустойчивости системы. 65 | 66 | --- 67 | 68 | ## Процесс записи данных 69 | 70 | При записи файла клиент сначала обращается к NameNode, запрашивая список подходящих DataNode, куда можно разместить блоки файла. После получения этого списка клиент напрямую отправляет блоки данных на указанные узлы. DataNode сохраняют полученные блоки и автоматически начинают процесс репликации — копируя блоки на другие узлы, согласно заданному фактору. После успешной записи и репликации клиент получает подтверждение об успешном завершении операции. 71 | 72 | --- 73 | 74 |

75 | hadoop 76 |

77 | 78 | ## Репликация в HDFS 79 | 80 | Для обеспечения надёжности и защиты от потери данных HDFS использует механизм репликации: каждый блок файла сохраняется в нескольких копиях. По умолчанию применяется три реплики (фактор репликации = 3). Система устроена так, что ни один DataNode не хранит более одной копии одного и того же блока. Обычно HDFS размещает две копии в пределах одной стойки, а третью — в другой стойке, чтобы сохранить данные даже при выходе из строя целой стойки. 81 | 82 | 83 | --- 84 | 85 |

86 | hadoop 87 |

88 | 89 | ## Secondary NameNode 90 | 91 | Несмотря на своё название, Secondary NameNode не является резервной копией основного узла. Его задача — периодически создавать контрольные точки (checkpoints), объединяя журнал операций (edits) с текущим образом файловой системы (fsimage) в единый файл. Это помогает снизить нагрузку на NameNode и упрощает его перезапуск. Secondary NameNode работает отдельно и должен быть настроен вручную. 92 | 93 | --- 94 | 95 | ## Проблема мелких файлов 96 | 97 | Маленькие файлы представляют собой серьёзную проблему для HDFS, так как каждый из них требует хранения отдельной записи в оперативной памяти NameNode. Поскольку NameNode ограничен объёмом доступной памяти, большое количество мелких файлов может привести к её исчерпанию. Это снижает общую производительность системы и ограничивает её масштабируемость. Поэтому HDFS гораздо эффективнее работает с крупными файлами, объединяющими множество мелких данных. 98 | 99 | --- 100 | 101 | ## 💻 CLI-команды HDFS 102 | 103 | | Категория | Команда | Описание | 104 | |--------------------------|--------------------------------------------------------|-----------------------------------------------| 105 | | Работа с файлами | `hdfs dfs -ls /путь` | Просмотр содержимого директории | 106 | | | `hdfs dfs -mkdir /путь` | Создание новой директории | 107 | | | `hdfs dfs -put файл /hdfs/путь` | Загрузка файла в HDFS | 108 | | | `hdfs dfs -get /hdfs/файл путь` | Скачивание файла из HDFS | 109 | | | `hdfs dfs -cat /файл` | Просмотр содержимого файла | 110 | | | `hdfs dfs -rm /файл` | Удаление файла | 111 | | | `hdfs dfs -rm -r /каталог` | Рекурсивное удаление каталога | 112 | | | `hdfs dfs -mv /старый /новый` | Переименование или перемещение файла | 113 | | Права и доступ | `hdfs dfs -chmod 755 /путь` | Изменение прав доступа | 114 | | | `hdfs dfs -chown пользователь:группа /путь` | Изменение владельца | 115 | | | `hdfs dfs -chgrp группа /путь` | Изменение группы | 116 | | Репликация | `hdfs dfs -setrep -w 2 /файл` | Установка фактора репликации | 117 | | | `hdfs dfs -getrep /файл` | Просмотр текущего уровня репликации | 118 | | Инфо о системе | `hdfs dfsadmin -report` | Информация о состоянии DataNode | 119 | | | `hdfs dfs -du -h /путь` | Размер директории/файла | 120 | | | `hdfs dfs -df -h` | Использование пространства в HDFS | 121 | | | `hdfs dfs -count /путь` | Количество файлов, директорий и байт | 122 | 123 | --- 124 | 125 | ## Типичные вопросы на собеседовании 126 | 1. Что такое DataNode и NameNode? 127 | 2. Что такое Secondary NameNode? 128 | 3. Какие операции можно делать с файлами? 129 | 4. Можно ли добавить информацию в файл на hdfs? 130 | 5. Проблема мелких файлов что это такое? 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /JOB/README.md: -------------------------------------------------------------------------------- 1 | # Работа 2 | 3 | > **Person A:** What's your job? 4 | 5 | > **Person B:** I'm a data engineer. 6 | 7 | > **Person B:** And what's your job? 8 | 9 | > **Person A:** Blow job. 10 | 11 | *** 12 | ### Раздаю БАЗУ 13 | 14 | Краткие тезисы, которые вы должны запомнить: 15 | 16 | - Крутое резюме не требует откликов. Рекрутеры приходят к вам сами. 17 | - Если на вакансии 100 и более откликов это не значит, что все они релевантные. Плюс вакансия может лежать уже долгое время и большую часть кандидатов просто отсеяли. Хочешь откликнуться - делай это! 18 | - С сопроводительным письмом лучше, чем без него. Хуже не сделает 19 | - Если ты джун, то ищи команду, где есть сеньоры и мидлы. Будешь у них учиться первое время. 20 | - Отказывайся от предложений по работе, где ты будешь первым и единственным дата инженером. На тебя повесят все гавно. 21 | - Дают тестовое? Делай. Половина твоих конкурентов забьют на это. Увеличивай свои шансы в этой воронке. 22 | - На собесе продавай так, будто ты строил ракету самому Илону Маску. Твои софты - это новая нефть. Душных задротов никто не любит. На работе ищут не только специалиста, но и коллегу, с которым будут пить пиво в баре по пятницам и орать караоке, поэтому будь приятным человеком. 23 | 24 | ## Где искать работу? 25 | 26 | Если у тебя отличное резюме, тогда работа ищет тебя сама. Если до сих пор нет никаких приглашений на тех собесы, значит твое резюме - отстой. Переделывай. 27 | 28 | Как правило рекрутеры приходят с 2-3 источников: 29 | 1. HH.ru 30 | 2. Habr Карьера 31 | 3. LinkedIn 32 | 33 | По графику работы джуну чаще будут предлагать офис или гибрид. Полной удаленки реально меньше для начинающих, поэтому придется с этим смириться, либо пробовать искать самому и пробивать лучший вариант (такое бывает). Когда я собесился на свою первую работу, мне предлагали джуном в Точка Банк. Там удаленка мир. Но я на тот момент уже получил оффер в Сбер и меня ничего более не волновало. 34 | 35 | ## Как и сколько просить денег? 36 | Итак, к вам приходит рекрутер и спрашивает вопросы про деньги. Вы естественно боитесь, но вот вам готовые скрипты для **ДЖУНА**. 37 | 38 | **Основное правило = 120к на руки в месяц** 39 | 40 | > Для вас не существует другого числа. На рынке эти деньги есть и их джунам платят (24-25гг). Если в момент, когда вы это читаете, инфляция улетела в небеса, значит умножаете 120к на коэффициент инфляции. 41 | 42 | ### Диалог #1 43 | 44 | > **Рекрутер:** Каковы ваши зарплатные ожидания? 45 | 46 | > **Джун:** Рассматриваю от 120к на руки. 47 | 48 | > **Рекрутер:** Вы не входите в нашу вилку. 49 | 50 | > **Джун:** Скажите, а какой верхний порог? 51 | 52 | > **Рекрутер:** У нас до 110к до вычета налогов. 53 | 54 | > **Джун:** Спасибо, мне не подходит, до свидания. 55 | 56 | ### Диалог #2 57 | 58 | > **Рекрутер:** Каковы ваши зарплатные ожидания? 59 | 60 | > **Джун:** Рассматриваю от 120к на руки. 61 | 62 | > **Рекрутер:** Да, вы входите в нашу вилку. Можем пообщаться. 63 | 64 | > **Джун:** Скажите, а это в месяц на руки или совокупный доход вместе с премией? 65 | 66 | > **Рекрутер:** Да, это совокупный доход вместе с премией. 67 | 68 | > **Джун:** Спасибо, а какой доход в месяц на руки тогда? 69 | 70 | > **Рекрутер:** 80к на руки после всех налогов. 71 | 72 | > **Джун:** Спасибо, мне не подходит, до свидания. 73 | 74 | ### Диалог #3 75 | 76 | > **Рекрутер:** Каковы ваши зарплатные ожидания? 77 | 78 | > **Джун:** Рассматриваю от 120к на руки. 79 | 80 | > **Рекрутер:** Да, вы входите в нашу вилку. Можем пообщаться. 81 | 82 | > **Джун:** Скажите, а это в месяц на руки или совокупный доход вместе с премией? 83 | 84 | > **Рекрутер:** Это уже на руки каждый месяц после вычета налогов. 85 | 86 | > **Джун:** Отлично, готов пообщаться. 87 | 88 | ## Как выбрать лучшее место? 89 | 90 | Значит у вас должно сойтись **минимум ДВА** условия из трех: 91 | 1. Хорошая зарплата ✅ 92 | 2. Классные коллеги ✅ 93 | 3. Интересные задачи ✅ 94 | 95 | | **Оптимально** | Степень комфорта | 96 | |----------------------------------|--------| 97 | | **Хорошая зарплата и Классные коллеги** | 90% | 98 | | **Хорошая зарплата и Интересные задачи** | 80%| 99 | | **Интересные задачи и Классные коллеги** | 70%| 100 | 101 | Как правило такое бывает не всегда, поэтому ориентируйтесь на это правило и держите голову в трезвом уме и светлом здравии. Компании вы никто и свечку держать они за вас не будут. Это бизнес, где вы наемный сотрудник. 102 | 103 | ## Как часто менять работу? 104 | 105 | Ситуации, когда надо менять работу: 106 | 1. Хочешь выше зарплату (х2 от текущей) 107 | 2. Однотипные задачи (не чувствуешь рост) 108 | 3. Скудный стек (устаревшие технологии) 109 | 4. Отстойные коллеги (душнилы беспросветные) 110 | 5. Хочешь на удаленку (сейчас офис или гибрид) 111 | 112 | Здесь нет привязки к времени. Если вы ушли на испытательном сроке, то рекрутеру об этом говорить не надо. Для нее этого опыта не должно существовать. Для нее будет хорошо, что вы работали на крайнем месте работы от 1 года и больше. В трудовую книжку на стадии собеса заглядывать не могут. А уже после оффера всем будет плевать на ваш опыт. Вас уже взяли, премии за вас все получили. Кайфуйте. 113 | 114 | Оптимально, если вы смените свою первую работу через год и уйдете на x2 от текущей зарплаты. Рынок сам решит, стОите вы этого или нет, но практика показывает, что те, кто сидит на одном месте 2-3 года, только проигрывают в доходе. Поэтому уже будучи наемным сотрудником ходите по собесам и прощупывайте рынок. 115 | 116 | ## Почему хотите сменить работу? Что отвечать? 117 | 118 | > **Рекрутер:** Скажите, а почему хотите сменить работу? 119 | 120 | > **Джун:** Вы знаете, у меня сейчас офис и хочется попробовать гибрид или удаленку. А так на текущем месте мне все нравится. Но на формат работы не повлиять, к сожалению... 121 | 122 | > **Рекрутер:** Да, понимаю вас. А если говорить про то, что для вас важно в первую очередь в компаниях? 123 | 124 | > **Джун:** В первую очередь ищу подходящий формат работы, потом интересно поработать с Кафкой (можно и другое назвать). У нас с ней не предвидится задач в ближайшем будущем. И конечно, хотелось бы увеличить свой доход. Хочется расти не только в компетенциях, но и в доходе.. 125 | 126 | > **Рекрутер:** Да, отлично. Предлагаю тех собес в Четверг! -------------------------------------------------------------------------------- /KAFKA/README.md: -------------------------------------------------------------------------------- 1 | ## Куратор раздела 2 | 3 | 4 | 5 | **Подвальный Артем**, 6 | _Data Engineer/Data Scientist_ 7 | 8 | [Канал Data Engineer Lab](https://t.me/dataengineerlab) 9 | 10 | Хочешь перейти в дата-инженерию, но не знаешь с чего начать? Пиши - составим резюме, продумаем твое развитие [https://t.me/ampodvalniy](https://t.me/ampodvalniy) 11 | 12 | 13 | Хочешь улучшить текущий раздел, внести недостающее или поправить формулировку? Предлагай PR и тегай [@Artemlin6231](https://github.com/Artemlin6231) 14 | 15 | 16 | ## Немного об этой главе 17 | Apache Kafka используется во всех бигтех-компаниях, и дата-инженеры с ней постоянно взаимодействуют, поэтому понимание принципов её работы полезно 18 | 19 | Приятного изучения) 20 | 21 | 22 | 23 | 24 | # Введение в брокеры сообщений 25 | 26 | **Брокеры сообщений** — это программные системы, обеспечивающие передачу данных (сообщений) между различными приложениями или сервисами. Они выступают в роли посредника между отправителями (продюсерами) и получателями (консьюмерами), снижая связность компонентов, повышая масштабируемость и обеспечивая надёжную доставку данных. 27 | 28 | --- 29 | 30 | ## Ключевые функции брокеров сообщений 31 | 32 | ### Организация передачи данных 33 | - Приём сообщений от отправителей (продюсеров). 34 | - Временное хранение сообщений. 35 | - Надёжная доставка сообщений получателям (консьюмерам). 36 | 37 | ### Снижение связности компонентов 38 | - Асинхронное взаимодействие: получатель может быть временно недоступен. 39 | - Унифицированный механизм обмена данными снижает зависимость между системами. 40 | 41 | ### Масштабируемость 42 | - Обработка больших объёмов данных за счёт **горизонтального масштабирования** и **распределения нагрузки**. 43 | 44 | ### Надёжность 45 | - Гарантированная доставка сообщений даже при сбоях или отказах отдельных компонентов. 46 | 47 | --- 48 | 49 | ## Примеры брокеров сообщений 50 | 51 | | Тип | Примеры | Особенности | 52 | |--------------------|-----------------------|--------------------------------------------| 53 | | Очереди сообщений | RabbitMQ, Amazon SQS | Каждое сообщение читается только одним консьюмером | 54 | | Брокеры (pub/sub) | Apache Kafka, Google Pub/Sub | Сообщения доступны многим подписчикам | 55 | --- 56 | 57 | > Брокеры сообщений являются основой современных распределённых систем, микросервисной архитектуры и стриминговых платформ. 58 | 59 | 60 | # Apache Kafka: Архитектура и Преимущества 61 | 62 | ## Что такое Apache Kafka? 63 | 64 |

65 | hadoop 66 |

67 | 68 | **Apache Kafka** — это распределённая платформа потоковой передачи сообщений, предназначенная для обработки больших объёмов данных в реальном времени. Kafka используется для обмена сообщениями между приложениями, аналитики, мониторинга и построения событийно-ориентированной архитектуры. 69 | 70 | --- 71 | 72 | ## Основные преимущества Kafka 73 | 74 | ### Низкая задержка (Latency) 75 | - Обработка сообщений за 1–10 мс. 76 | - Подходит для real-time аналитики, мониторинга, логирования. 77 | 78 | ### Высокая пропускная способность (Throughput) 79 | - Поддержка миллионов сообщений в секунду. 80 | - Эффективна при потоковой обработке больших объемов данных. 81 | 82 | ### Гибкое хранение 83 | - Сообщения сохраняются на диск. 84 | - Можно задавать время хранения или лимит объема. 85 | 86 | ### Поддержка нескольких потребителей 87 | - Сообщения доступны нескольким консьюмерам параллельно. 88 | 89 | ### Масштабируемость 90 | - Kafka масштабируется горизонтально: можно добавлять новые брокеры без остановки кластера. 91 | 92 | --- 93 | 94 | ## Архитектура Kafka: Топики и Партиции 95 | 96 | ### Topic 97 | - Логическая категория данных (как "папка"). 98 | - Содержит сообщения, упорядоченные в очереди. 99 | 100 | ### Partition 101 | - Топик делится на **партиции** — независимые, упорядоченные логи сообщений. 102 | - Партиции позволяют масштабировать топик горизонтально. 103 | 104 | ```text 105 | Topic: "Orders" 106 | Partition 0: [msg1, msg2, msg3] 107 | Partition 1: [msg4, msg5, msg6] 108 | Partition 2: [msg7, msg8, msg9] 109 | Partition 3: [msg10, msg11, msg12] 110 | ``` 111 | 112 | --- 113 | 114 | ## Как работает Kafka 115 | 116 | ### Продюсеры (Producers) 117 | Продюсеры отправляют сообщения в партиции топика. Распределение сообщений может происходить: 118 | - случайным образом, 119 | - равномерно, 120 | - по **ключу (key)** — все сообщения с одним и тем же ключом попадают в одну партицию. 121 | 122 | ### Консьюмеры (Consumers) 123 | Консьюмеры читают сообщения из партиций. В рамках **одной consumer-группы**: 124 | - Каждая партиция обрабатывается только **одним** консьюмером. 125 | - Несколько консьюмеров могут параллельно обрабатывать разные партиции одного топика. 126 | 127 | --- 128 | 129 | ## Зачем нужны партиции? 130 | 131 | ### Горизонтальное масштабирование 132 | Партиции могут храниться на разных брокерах, что позволяет распределять данные по кластеру. 133 | 134 | ### Балансировка нагрузки 135 | Каждая партиция может обрабатываться отдельным консьюмером, позволяя масштабировать обработку сообщений. 136 | 137 | ### Повышение пропускной способности 138 | Сообщения из разных партиций могут обрабатываться параллельно, что увеличивает throughput Kafka. 139 | 140 | ### ⚠Важно: 141 | Порядок сообщений сохраняется **только внутри одной партиции**. 142 | 143 | --- 144 | 145 | ## Offset — механизм отслеживания прогресса 146 | 147 | **Offset** — уникальный идентификатор (номер) каждого сообщения внутри партиции. 148 | 149 | Он используется консьюмерами для: 150 | - Определения, какие сообщения уже были прочитаны. 151 | - Продолжения чтения с нужного места при повторном запуске. 152 | 153 | ### Пример: 154 | ```text 155 | Messages: [msg1, msg2, msg3] 156 | Offsets: [ 0 , 1 , 2 ] 157 | ``` 158 | 159 | Если консьюмер дошёл до offset = 1, при следующем запуске он начнёт с offset = 2. 160 | 161 | --- 162 | 163 | ## Структура сообщения Kafka 164 | 165 | - **Key** — влияет на выбор партиции. 166 | - **Value** — основное содержимое (например, JSON, строка, байты и т.д.). 167 | - **Метаданные**: 168 | - Offset 169 | - Timestamp 170 | - Headers (доп. данные) 171 | 172 | --- 173 | 174 | ## Почему нельзя полагаться на timestamp 175 | 176 | ### Возможные проблемы: 177 | 1. **Разные источники времени**: часы продюсеров и брокеров могут не совпадать. 178 | 2. **Сетевые задержки**: сообщение может прийти позже, чем было создано. 179 | 3. **Изменение timestamp**: при повторной отправке или обработке в Kafka Streams. 180 | 181 | ### Рекомендация: 182 | Добавляйте поле `event_time` в value — оно фиксирует бизнес-время события независимо от системных часов. 183 | 184 | --- 185 | 186 | ## Использование Kafka 187 | 188 | - Взаимодействие между микросервисами. 189 | - Реализация pub/sub-архитектуры. 190 | - Потоковая аналитика и обработка логов. 191 | - Интеграция с Apache Spark, Flink, Hadoop. 192 | 193 | --- 194 | 195 | ## Дополнительно 196 | 197 | - Официальный сайт: [https://kafka.apache.org](https://kafka.apache.org) 198 | - Документация: [https://kafka.apache.org/documentation](https://kafka.apache.org/documentation) 199 | 200 | --- 201 | 202 | # Продюсеры, Консьюмеры и Консьюмер-группы в Apache Kafka 203 | 204 | Apache Kafka реализует модель publish/subscribe, в которой данные публикуются **продюсерами** (producers), а затем читаются **консьюмерами** (consumers). Для масштабируемой и отказоустойчивой обработки данных консьюмеры могут объединяться в **группы потребителей** (consumer groups). 205 | 206 | --- 207 | 208 | ## Продюсеры (Producers) 209 | 210 | Приложения или сервисы, которые формируют и отправляют сообщения в определённые **топики Kafka**. 211 | 212 | ### Принцип работы 213 | 214 |

215 | hadoop 216 |

217 | 218 | #### Распределение по партициям: 219 | - Если указан **ключ (key)** — Kafka использует хеширование ключа для выбора партиции. 220 | - Если ключ не задан — используется стратегия **round-robin** (равномерное распределение). 221 | 222 | #### Асинхронная отправка: 223 | - Сообщения группируются в **батчи (batches)** для повышения производительности. 224 | - Поддерживается как **асинхронная**, так и **синхронная** отправка. 225 | 226 | #### Гарантия доставки (acks): 227 | - `acks=0` — без подтверждения (максимальная производительность, низкая надёжность). 228 | - `acks=1` — подтверждение от лидера партиции. 229 | - `acks=all` — подтверждение от всех реплик (максимальная надёжность). 230 | 231 | --- 232 | 233 | ### Операция Produce 234 | 235 | Продюсер формирует сообщение, которое включает: 236 | - **Key** — определяет выбор партиции. 237 | - **Value** — основное содержимое сообщения. 238 | - **Headers** — дополнительные метаданные (опционально). 239 | 240 | Сообщение отправляется в Kafka-брокер и записывается в конец партиции. Kafka назначает **offset** и, в зависимости от настроек `acks`, возвращает подтверждение. 241 | 242 | **Поток данных:** 243 | `Producer → Kafka Broker → Partition` 244 | 245 | --- 246 | 247 | ### Основные настройки продюсера: 248 | - `acks` — уровень подтверждения. 249 | - `batch.size` — максимальный размер батча. 250 | - `linger.ms` — время ожидания перед отправкой батча. 251 | 252 | --- 253 | 254 | ## Консьюмеры (Consumers) 255 | Приложения или сервисы, которые считывают сообщения из топиков Kafka. 256 | 257 | ### Принцип работы 258 | 259 | #### Подписка: 260 | - Консьюмер подписывается на один или несколько топиков. 261 | - Kafka автоматически распределяет партиции между участниками **одной группы**. 262 | 263 | #### Обработка сообщений: 264 | - Чтение сообщений в порядке их поступления (по offset). 265 | - Консьюмер отслеживает **текущий offset** для восстановления при сбоях. 266 | 267 | #### Подтверждение обработки: 268 | - **Автоматическое:** offset обновляется автоматически после обработки. 269 | - **Ручное:** offset обновляется вручную — повышает надёжность и контроль. 270 | 271 | --- 272 | 273 | ### Операция Fetch 274 | 275 | Консьюмер выполняет запрос **Fetch** к брокеру для получения сообщений из партиций, начиная с нужного offset. 276 | 277 | **Поток данных:** 278 | `Consumer → Kafka Broker (Fetch Request) → Consumer (Messages)` 279 | 280 | --- 281 | 282 | ### Основные настройки консьюмера: 283 | - `fetch.min.bytes` — минимальный объём данных в одном ответе. 284 | - `fetch.max.wait.ms` — максимальное время ожидания, если данных мало. 285 | - `max.poll.records` — количество сообщений за один запрос. 286 | 287 | --- 288 | 289 | ## Консьюмер-группы (Consumer Groups) 290 | 291 | - Сообщения из одной партиции обрабатываются **только одним** участником группы. 292 | - Разные группы могут обрабатывать один и тот же топик **независимо**. 293 | - Это обеспечивает параллелизм и горизонтальное масштабирование. 294 | 295 | --- 296 | 297 | ## Полезные ресурсы 298 | 299 | - [Kafka Producer API](https://kafka.apache.org/documentation/#producerapi) 300 | - [Kafka Consumer API](https://kafka.apache.org/documentation/#consumerapi) 301 | 302 | -------------------------------------------------------------------------------- /Linux/README.md: -------------------------------------------------------------------------------- 1 | # Основные команды в Linux 2 | 3 | В работе тебе придется часто работать с терминалом (командной строкой Linux или bash-строкой). 4 | Команды ниже являются самыми популярными и часто используемыми, поэтому не поленись и потренируйся на них у себя локально. 5 | В операционной системе Windows с bash-строкой можно поработать используя Git Bash, установленный на предыдущем шаге, либо через WSL (Windows Subsystem for Linux). 6 | 7 | 8 | - ls - список файлов и директорий в текущем каталоге 9 | ```bash 10 | ls -l # подробный список 11 | ls -a # включая скрытые файлы 12 | ``` 13 | - cd - смена текущего каталога 14 | ```bash 15 | cd /path/to/directory 16 | cd .. # выйти из текущей папки на уровень выше 17 | ``` 18 | - pwd - показать текущий путь в каталог, где вы находитесь 19 | ```bash 20 | pwd 21 | ``` 22 | - cp - копирование файлов и директорий 23 | ```bash 24 | cp source destination 25 | ``` 26 | - mv - перемещение или переименование файлов и директорий 27 | ```bash 28 | mv source destination 29 | - touch - создание файлов 30 | ```bash 31 | touch file.txt # создать файл 32 | ``` 33 | - vim - встроенный редактор кода 34 | ```bash 35 | vim my_code.py 36 | # Чтобы отредактировать текст, нужно нажать i (insert, режим ввода) 37 | # Чтобы выйти из vim, нужно нажать esc (выход из режима ввода), потом :wq (это сохраняет файл и выходит из него) 38 | ``` 39 | - rm - удаление файлов и директорий 40 | ```bash 41 | rm file 42 | rm -r directory # удаление директории и её содержимого 43 | ``` 44 | - cat - вывод содержимого файла. 45 | ```bash 46 | cat file 47 | ``` 48 | - less - режим постраничного просмотра содержимого файла. 49 | ```bash 50 | less file 51 | ``` 52 | - tail -f - режим просмотра окончания файла в режиме реального времени (если, например, файл продолжает наполняться данными). 53 | ```bash 54 | tail -f file 55 | ``` 56 | - grep - поиск строк в файле. 57 | ```bash 58 | grep "apple" file 59 | ``` 60 | - chmod - изменение прав доступа к файлам и директориям. 61 | ```bash 62 | chmod 755 test.txt 63 | ``` 64 | - echo - запись в файл 65 | ```bash 66 | echo "data goes to file" >> data.txt 67 | ``` 68 | - mkdir - создать директорию (папку) 69 | ```bash 70 | mkdir halltape_directory 71 | mkdir -m 755 halltape_directory # Создание каталога с заданными правами доступа 72 | ``` 73 | - history - показать историю команд 74 | ```bash 75 | history 76 | ``` 77 | 78 | Пример использования chmod (пригодится, когда нужно, чтобы файл мог запускаться сторонней программой и не было конфликтов) 79 | - Создадим файл и изменим права доступа (смотрите, как меняются права доступа в буквенном выражении) 80 | ```bash 81 | halltape@MacBookPro Desktop % touch test.txt 82 | halltape@MacBookPro Desktop % ls -l 83 | -rw-r--r-- 1 halltape staff 0 Oct 3 12:37 test.txt 84 | halltape@MacBookPro Desktop % chmod 755 test.txt 85 | halltape@MacBookPro Desktop % ls -l 86 | -rwxr-xr-x 1 halltape staff 0 Oct 3 12:37 test.txt 87 | halltape@MacBookPro Desktop % chmod 777 test.txt 88 | halltape@MacBookPro Desktop % ls -l 89 | -rwxrwxrwx 1 halltape staff 0 Oct 3 12:37 test.txt 90 | ``` 91 | 92 | Таблица с обозначениями для chmod 93 | | Число | Право доступа | 94 | |-------|---------------------------------| 95 | | 0 | отсутствие прав (---) | 96 | | 1 | разрешено только исполнение (--x) | 97 | | 2 | разрешена только запись (-w-) | 98 | | 3 | разрешены запись и исполнение (-wx) | 99 | | 4 | разрешено только чтение (r--) | 100 | | 5 | разрешены чтение и исполнение (r-x) | 101 | | 6 | разрешены чтение и запись (rw-) | 102 | | 7 | полные права (rwx) | 103 | 104 | Используя команды, указанные выше, можно воспользоваться встроенными утилитам Linux, например планировщиком cron. 105 | cron позволяет автоматически выполнять скрипты или команды в заданное время. 106 | Для пользователей Windows на данном этапе необходима установка WSL, в Git Bash утилита cron отсутствует. 107 | Основные шаги по использованию: 108 | 109 | - crontab -e - отредактировать файл cron 110 | ```bash 111 | crontab -e 112 | ``` 113 | 114 | Запись в crontab имеет следующий формат: 115 | 116 | \* * * * * команда 117 | 118 | Где: 119 | 120 | Первая * — минута (0-59) 121 | Вторая * — час (0-23) 122 | Третья * — день месяца (1-31) 123 | Четвёртая * — месяц (1-12) 124 | Пятая * — день недели (0-7) (где 0 и 7 — воскресенье) 125 | 126 | Например: 127 | - Создадим задачу на запуск python-скрипта (script.py) каждый день в 7 вечера, для этого откроем файл cron: 128 | ```bash 129 | halltape@MacBookPro Desktop % crontab -e 130 | ``` 131 | 132 | - Если вы не создавали ранее файл cron, появится сообщение с выбором текстового редактора (можно воспользоваться vim или nano): 133 | 134 | no crontab for npc - using an empty one 135 | 136 | Select an editor. To change later, run 'select-editor'. 137 | 1. /bin/nano <---- easiest 138 | 2. /usr/bin/vim.basic 139 | 3. /usr/bin/vim.tiny 140 | 4. /bin/ed 141 | 142 | - Нажимаем 1 и попадаем через редактор nano в файл cron, где в виде комментариев будет инструкция по использованию. Эти записи можно оставить как подсказки и после них сделать запись (путь к файлу можно определить через команду pwd, команда python3 запустит скрипт по указанному пути): 143 | 144 | 0 19 * * * python3 /home/script.py 145 | 146 | - Сохраняем (в редакторе nano: сочетанием клавиш ctrl + s) и выходим (nano: ctrl + x), видим сообщение об успешной уставноке новой задачи: 147 | 148 | crontab: installing new crontab 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /NF/README.md: -------------------------------------------------------------------------------- 1 | # Нормальные формы 2 | 3 | **1НФ, 2НФ, 3НФ** 4 | 5 | Предисловие: 6 | На большинстве собесов спрашивают только про первые три нормальные формы. Можете в качестве эрудиции погуглить про 4НФ, 5НФ и 6НФ и блеснуть эрудицией на собеседовании. 7 | 8 |

9 | 10 |

11 | 12 | 13 | Нормальные формы спрашивают на собесах, а также они будут попадаться у вас на работе, поэтому стоит знать точно за первые три формы. Грубо говоря, нормальная форма – это то, на сколько частей стоит разбить таблицу, чтобы с ней было удобно работать на вставку, удаление или изменение данных. Если будем хранить все данные в рамках одной таблицы, то могут возникнуть сложности с удалением дубликатов, изменением данных (например изменить номер телефона клиента придется во всех местах всей таблицы) и так далее. Подробности смотрите в видео по ссылке ниже! 14 | 15 | Видео ➜ [1НФ, 2НФ, 3НФ нормальные формы](https://www.youtube.com/watch?v=zwQzL80U51c) 16 | 17 | Читать ➜ [Хабр статья про нормальные формы](https://habr.com/ru/articles/254773) 18 | 19 | Скачать PDF ➜ [Конспект про нормальные формы](../files/normal_tables.pdf) -------------------------------------------------------------------------------- /PET_PROJECT/README.md: -------------------------------------------------------------------------------- 1 | # Pet Project 2 | 3 | ## Содержание страницы 4 | 5 | - [Pet Project](#pet-project) 6 | - [Содержание страницы](#содержание-страницы) 7 | - [Проекты](#проекты) 8 | - [Проект №0 - Sandbox DB](#проект-0---sandbox-db) 9 | - [Проект №1 - HalltapeETLPipeline](#проект-1---halltapeetlpipeline) 10 | - [Проект №2 - spacex-api-analize](#проект-2---spacex-api-analize) 11 | - [Проект №3 - Create mart in PySpark](#проект-3---create-mart-in-pyspark) 12 | - [Проект №4 - От почтового сервера до Greenplum](#проект-4---от-почтового-сервера-до-greenplum) 13 | - [Открытые API для проектов](#открытые-api-для-проектов) 14 | 15 | ## Проекты 16 | 17 | ### Проект №0 - Sandbox DB 18 | 19 | **Песочница для Дата Инженера** ➜ [Sandbox DB](https://gitflic.ru/project/ananevsyu/sandbox_db_public) 20 | 21 | --- 22 | 23 | ### Проект №1 - HalltapeETLPipeline 24 | 25 |

26 | 27 |

28 | 29 | 30 | >Важно! Этот проект был таким не сразу. Первые его версии содержали только Airflow, Clickhouse и Pandas под капотом. Поэтому не думайте, что я сразу был суперменом. Все добавлялось и допиливалось уже позже. Но база была та же. 31 | 32 | Любой пет проект ты можешь собрать, как с нуля, так и взять готовый шаблон по типу моего. В проекте ниже есть минимальный набор необходимых инструментов. Твоя задача – настроить ETL процесс. Данные можно, как сгенерировать свои, так и скачать по API или с любого другого ресурса. Ограничение только твоя фантазия. Этот проект больше, как шаблон. То, как выстроить весь процесс работы с данными – твоя задача. 33 | 34 | Вот, что там уже есть: 35 | - Генерация синтетических данных 36 | - Построение простой витрины данных на Spark 37 | - Мониторинг качества данных 38 | - dbt модель для витрины данных в Clickhouse 39 | - dbt модель для качества данных в Clickhouse 40 | 41 | Для сборки проекта тебе понадобятся знания [Git](../Git/README.md), Docker 42 | 43 | **Собери его у себя** ➜ [Pet Project HalltapeETLPipeline](https://github.com/halltape/HalltapeETL) 44 | 45 | --- 46 | ### Проект №2 - spacex-api-analize 47 | 48 | По всем вопросам по данному проекту можно обращаться к **Шустикову Владимиру** в телеграмм канале – [Инженерообязанный](https://t.me/Shust_DE) 49 | 50 |

51 | 52 |

53 | 54 | 55 | Задачами проекта является настройка ETL-процесса по загрузке данных из API в базу данных, настройка сетей и логической репликации данных, автоматизация создания аналитических запросов поверх сырых данных и визуальное представление результатов на дашборде. 56 | 57 | Здесь вы можете получить следующие знания: 58 | 59 | - Выгрузка данных из API на AirFlow 60 | - Работа с ООП 61 | - Настройка сетей, а именно IP-адресации 62 | - Логическая репликация в PostgreSQL 63 | - Работа с внешними источниками в Clickhouse на основе движка PostgreSQL 64 | - Построение моделей, тестов и макросов в DBT 65 | 66 | Для сборки проекта тебе понадобятся знания [Git](../Git/README.md), Docker 67 | 68 | **Собери его у себя** ➜ [Обработка данных SpaceX AP](https://github.com/ShustGF/spacex-api-analize) 69 | 70 | ____ 71 | ### Проект №3 - Create mart in PySpark 72 | 73 | По всем вопросам по данному проекту можно обращаться к **Шустикову Владимиру** в телеграмм канале – [Инженерообязанный](https://t.me/Shust_DE) 74 | 75 | Задачей данного проекта была сгенерировать сырые данные и на их основе построить несколько витрин данных. Более подробно с заданием проекта можно ознакомиться [здесь](https://docs.google.com/document/d/1xrlCK8Yw-qbmgmiAlY96x7UOGlu3ug3w/edit?usp=sharing&ouid=112563507644559378212&rtpof=true&sd=true). 76 | 77 |

78 | 79 |

80 | 81 | В этом проекты вы можете получить следующие знания: 82 | 83 | - программирования на Python 84 | - работа с Google Disk через код 85 | - написание кода на PySpark 86 | 87 | **Собери его у себя** 88 | 89 | Проект состоит из двух блокнотов: 90 | 91 | 1) [генерация файлов в Google Disk](https://colab.research.google.com/drive/1QJhmaAGopzt9t7oh9CV420mWCQAGD63i?usp=sharing) 92 | 2) [создание витрин данных](https://colab.research.google.com/drive/1Z5fVuajC1rLZQe_w2rJ2LFEzh1SV6KXq?usp=sharing) 93 | 94 | Для сборки проекта тебе понадобятся стабильный интернет и Google аккаунт. Вся инструкция по запуску описана в блокнотах. 95 | 96 | ____ 97 | ### Проект №4 - От почтового сервера до Greenplum 98 | 99 | 100 | По всем вопросам по данному проекту можно обращаться к [Кузьмину Дмитрию](https://t.me/dim4eg91) в телеграмм канале – [Дмитрий Кузьмин. Инженерия данных](https://t.me/kuzmin_dmitry91) 101 | 102 | 103 |

104 | 105 |

106 | 107 | - [ETL-проект для начинающих Data Engineers: От почтового сервера до Greenplum](https://github.com/dim4eg91/DataEngineering/blob/main/articles/ETL_as_a_pet_project.md) 108 | 109 | ## Открытые API для проектов 110 | 111 | * [Launch Library 2](https://thespacedevs.com/llapi) - Запуски ракет, космические события и космические полеты с экипажем. 112 | * [SpaceX API](https://github.com/r-spacex/SpaceX-API/tree/master/docs#rspacex-api-docs) - Информация о компании SpaceX. 113 | * [Wikimedia](https://dumps.wikimedia.org/other/) - Дампы данных о посмотрах страниц в Википедии в текстовом виде. -------------------------------------------------------------------------------- /QUESTION/AirFlow/README.md: -------------------------------------------------------------------------------- 1 | ## Вопросы по AriFlow. 2 | 3 | 1. Из каких основных частей состоит AirFlow? 4 | 2. Какие операторы вы знаете? 5 | 3. Что такое сенсер и для чего он нужен? 6 | 4. Таска в AirFlow упала с ошибкой, как сделать так, чтобы не смотря на ошибку, следующая таска запустилась? 7 | 5. Как в AirFlow в зависимости от условия, продолжить обработку по нужной ветки ДАГа? 8 | 6. Что такое XCOM? 9 | 7. Какие базы данных используется в Airflow? 10 | 8. Чем отличается Celery Executor и local executor? -------------------------------------------------------------------------------- /QUESTION/ClickHouse/README.md: -------------------------------------------------------------------------------- 1 | ## Вопросы по ClickHouse. 2 | 3 | 1. Принцип работы ClickHouse? 4 | 2. Какие основные движки ClickHouse ты знаешь? 5 | 3. Что такое гранулярность? 6 | 4. В чем различие primary key и order by при создании таблицы? 7 | 5. Где хранится индекс? 8 | 6. Что такое кардинальность и как она аффектит ключ распределения? 9 | 7. Что такое партиции и как они совмещены с primary key? 10 | 8. Как сделать таблицу распределённой в кластере? 11 | 9. Принцип работы MergeTree движков, и как хранятся данные? 12 | 10. Какие проблемы есть у движка ReplacingMergeTree? 13 | 11. Как в Clickhouse устроена операция UPDATE? 14 | 12. Какие индексы используются в ClickHouse? 15 | 13. Как работают JOIN в ClickHouse? 16 | 14. Как в ClickHouse распределяются таблицы между шардами? 17 | 15. Какая машина является координатором в распределённом ClickHouse? 18 | 16. Какими свойствами САР-теоремы обладает ClickHouse? 19 | 17. Почему в ClickHouse нет JOIN по неравенству? 20 | 18. В каком случае ClickHouse выберит физический вид MergeJOIN? 21 | 19. Как PSQL сортирует данные при MergeJOIN , и почему так нельзя сделать в ClickHouse? 22 | -------------------------------------------------------------------------------- /QUESTION/DWH/README.md: -------------------------------------------------------------------------------- 1 | ## Вопросы по хранилищам данных. 2 | 3 | 1. Что такое денормализованная таблица? 4 | 2. Для чего нужна нормализация таблиц? 5 | 3. Какие подходы построения хранилищ данных бывают? 6 | 4. Что такое OLTP и OLAP? Чем они отличаются? Приведи соответствущие примеры баз данных. 7 | 5. Объясни подход Кимбалла? 8 | 6. Объясни подход Инмона? 9 | 7. Объясни подход Data Vault 2.0? Чем отличается 1 и 2 версия DV? 10 | 8. Объясни подход Anchor Modeling? 11 | 9. Что такое SCD и какие типы бывают? 12 | 10. На какие слои делится ХД? И для чего они нужны? 13 | 11. Что представляет из себя ER-модели, какие связи могут быть? 14 | 12. Как заменяется связь "многие-ко-многим"? 15 | 13. Что такое Data Lake? и чем оно отличается от DWH? 16 | 14. Чем в хранилище ODS слой отличается от DDS слоя? 17 | 15. Что такое потоковая обработка данных и пакетная обработка данных? 18 | 16. Что такое и чем отличаются Концептуальная, Логическая и Физическая модели? -------------------------------------------------------------------------------- /QUESTION/Data_Base/README.md: -------------------------------------------------------------------------------- 1 | ## Видео с разбором вопросов по Базам Данных 2 | 3 |

ТОП вопросов на собеседовании по Базам Данных

4 | 5 | ### Часть 1. 6 | 7 | [![Топ вопросов на собеседовании по Базам Данных - Часть 1](https://markdown-videos-api.jorgenkh.no/youtube/rTSODCT4mKw)](https://youtu.be/lsG4KFWesxM) 8 | 9 | ## Вопросы по Базам Данных. 10 | 11 | 1. Для чего нужен ACID? Объясни своими словами понятия: Атомарность, Согласованность, Изоляция и Устойчивость. 12 | 2. Какие существуют уровни Изоляции в сатндарте SQL? 13 | 3. Что такое методология BASE и чем она отличается от ACID? 14 | 4. Что такое и для чего нужен индекс в БД? 15 | 5. Какие типы индексов существуют? 16 | 6. Чем отличается кластеризованный индек от некластеризованного? 17 | 7. Сколько у таблицы может быть кластеризованных индексов? 18 | 8. Можно ли строить индекс по JSON полям? 19 | 9. Чем отличается материализованное представление от нематериализованного? 20 | 10. Можно ли читать данные из материализованного представления, когда выполняется команда REFRESH? 21 | 11. Как устроена система транзакций в PostgreSQL? 22 | 12. Что из себя представляет СТЕ? 23 | 13. Какие виды баз данных ты знаешь? 24 | 14. Чем отличаются колоночные БД от строковых? 25 | 15. Для чего нужны схемы и табличные пространства? 26 | 16. Для чего нужна репликация данных, какие виды существуют и примеры сценариев репликаций? 27 | 17. Объясни CDC подход? 28 | 18. Что такое партицирование таблиц, их виды и примеры применения использования? 29 | 19. В каких случаях лучше использовать БД со строковым хранением, а в каких с колоночным? 30 | 20. Влияет ли колоночное хранение на скорость доступа к данным в случаях чтения, удаления и изменения? 31 | 21. За счет чего в стоковых БД мы можем быстрее обращаться к полному набору данных, в отличии от колоночных? 32 | 22. Что такое B-tree индекс? Как он работает? Какая сложность данного алгоритма? 33 | 23. Для чего используется шардирование и репликация? 34 | 24. Шардирование ускоряет работу запросов? 35 | 25. 36 | 37 | -------------------------------------------------------------------------------- /QUESTION/GreenPlum/README.md: -------------------------------------------------------------------------------- 1 | ## Вопросы по GreenPlum. 2 | 3 | 1. Что такое GreenPlum? 4 | 2. Что такое дистрибуция и какие виды существуют? 5 | 3. Что такое партицирование и какие виды существуют? 6 | 4. Что такое MPP-архитекрута? 7 | 5. Какие индексы существуют в GP? 8 | 6. Какие виды таблиц по хранению данных бывают в GP? 9 | 7. Какими методами можно подлючать внешние таблицы? 10 | 8. Какой порт используется по умолчанию для подключения к БД? -------------------------------------------------------------------------------- /QUESTION/Hadoop/README.md: -------------------------------------------------------------------------------- 1 | ## Вопросы по Hadoop. 2 | 3 | 1. Что такое Hadoop и из каких компонентов он состоит? 4 | 2. Что такое YARN? 5 | 3. Для чего нужен Apache Oozie? 6 | 4. Что такое Hive и объясни, как он работает с данными? 7 | 5. Объясни парадигму MapReduce и почему Spark пришел ей на замену? 8 | 6. Как работает HDFS? 9 | 7. Для чего нужна NameNode, Secondary NameNode? 10 | 8. Нам необходимо считать текстовый файл из HDFS, объясни, что будет происходить? 11 | 9. Что такое партиционирование и что оно из себя представляет в Hadoop? 12 | 10. Что такое фактор репликации в HDFS и для чего он нужен? 13 | 11. Что такое HDFS блоки и какие у них есть минусы? 14 | 12. Как бороться с маленькими файлами в HDFS? Переполнение NameNode 15 | 13. Если мы записываем файл размером меньше 128Мб, то какого размера будет блок нового файла? -------------------------------------------------------------------------------- /QUESTION/PySpark/README.md: -------------------------------------------------------------------------------- 1 | ## Вопросы по Spark(PySpark). 2 | 3 | 1. Что такое Spark? 4 | 2. Объясни парадигму MapReduce и почему Spark пришел ей на замену? 5 | 3. Что делает Shuffle в Spark? Между чем передаются данные? 6 | 4. Как передать UDF? 7 | 5. Какие типы трансформаций бывают? 8 | 6. Какие проблемы могут быть с shuffle? 9 | 7. Что такое spill? И в чем их причины? Какие варианты решения проблем со spill-файлами? 10 | 8. Что такое data skewing? Как можно решить данную проблему? 11 | 9. В чем различие coalesce и repartition? 12 | 10. Чем отличается RDD от DataFrame? 13 | 11. Для чего в Spark используется cache? 14 | 12. Почему нельзя использовать Pandas для больших данных, а нужно использовать Spark? 15 | 13. Минимальное параллелизм в Spark и что это такое? 16 | 14. Что такое RDD в Spark? 17 | 15. Что такое Dataset и чем отличается от dataframe и RDD? 18 | 16. Какие виды кэширования существуют в Spark и чем они отличаются? 19 | 17. Что такое persist в Spark и какие storage levels существуют? 20 | 18. Какие настройки Spark applications вы используете? 21 | 19. Что такое broadcast join в Spark и как его настроить? 22 | 20. Что такое ленивые вычисления в Spark? 23 | 21. Что такое Adaptive query execution? -------------------------------------------------------------------------------- /QUESTION/Python/README.md: -------------------------------------------------------------------------------- 1 | ## Вопросы по Python. 2 | 3 | 1. Лямбда функция (что это, зачем, где использовать)? 4 | 2. Назовите принципы ООП? 5 | 3. В чем разница "==" и "is"? 6 | 4. Что такое Self, для чего нужен, как и где используется? 7 | 5. В чем разница между определением функции func и func()? 8 | 6. Назови изменяемые и неизменяемые объекты. 9 | 7. Что такое Декоратор? 10 | 8. Что такое Генератор? Какие есть варианты определения генераторов? 11 | 9. Как рассчитывается сложность алгоритма? на примере list, tuple 12 | 10. Как передаются аргументы в функцию? 13 | 11. Что такое super() и зачем нужен? 14 | 12. Что такое итерация? Что такое итератор? 15 | 13. Можно ли на одну функцию нацепить несколько декораторов и как они будут считываться? 16 | 14. Функция, которая используется в качестве аргумента другой функции, может использовать свои аргументы? 17 | 15. Что представляет из себя тип данных Int в Python? 18 | 16. Какая типизация используется в Python? 19 | 17. Что может быть ключём словаря? 20 | 18. Класс вида: 21 | 22 | ``` 23 | class MyClass: 24 | pass 25 | ``` 26 | 27 | может быть ключём словаря? Если нет, то что необходимо добавить? 28 | 20. В чем различие между return и yield? 29 | 21. Что обозначает ключевое слово is? 30 | 22. Есть функция, в ней передается аргумент **qwe, что это обозначает? 31 | 23. Что такое try, except, else, finally? 32 | 24. Что выведет print(a)? 33 | 34 | ``` 35 | a = [1,2,3] 36 | b = a 37 | b.append(4) 38 | ``` 39 | 25. Как работает сборщик мусора в python? 40 | 26. Как работает память в питоне? 41 | 27. Можно ли в словарь в key записать изменяемый тип? Почему? -------------------------------------------------------------------------------- /QUESTION/README.md: -------------------------------------------------------------------------------- 1 | ## Куратор раздела 2 | 3 | 4 | 5 | **Шустиков Владимир**, оставивший военную жизнь позади и ушедший в данные с головой. Работаю с данными более 2х лет и останавливаться не собираюсь! Веду: 6 | 7 | [Telegram канал](https://t.me/Shust_DE) 8 | 9 | [Youtube канал](https://www.youtube.com/@shust_de) 10 | 11 | Если хочешь сменить текущую профессию на Дата Инженера — пиши не стесняйся, я сам проходил этот нелегкий путь и тебе помогу https://t.me/ShustDE. 12 | 13 | Хочешь добавить вопрос или тему? Предлагай PR и тегай [@ShustGF](https://github.com/ShustGF) или пиши в личку [Telegram](https://t.me/ShustDE). 14 | 15 | ----------------- 16 | 17 | ## Темы вопросов: 18 | 19 | 1) [SQL](SQL/README.md) 20 | 2) [AirFlow](AirFlow/README.md) 21 | 3) [Python](Python/README.md) 22 | 4) [DWH](DWH/README.md) 23 | 5) [Data_Base](Data_Base/README.md) 24 | 6) [GreenPlum](GreenPlum/README.md) 25 | 7) [ClickHouse](ClickHouse/README.md) 26 | 8) [Hadoop](Hadoop/README.md) 27 | 9) [PySpark](PySpark/README.md) 28 | -------------------------------------------------------------------------------- /QUESTION/SQL/README.md: -------------------------------------------------------------------------------- 1 | ## Видео с разбором вопросов по SQL 2 | 3 |

ТОП вопросов на собеседовании по SQL

4 | 5 | ### Часть 1. 6 | 7 | [![Топ вопросов на собеседовании по SQL - Часть 1](https://markdown-videos-api.jorgenkh.no/youtube/rTSODCT4mKw)](https://youtu.be/rTSODCT4mKw) 8 | 9 | ### Часть 2. 10 | 11 | [![Топ вопросов на собеседовании по SQL - Часть 2](https://markdown-videos-api.jorgenkh.no/youtube/rTSODCT4mKw)](https://youtu.be/ssmmckc3F3c) 12 | 13 | ### Часть 3. 14 | 15 | [![Топ вопросов на собеседовании по SQL - Часть 3](https://markdown-videos-api.jorgenkh.no/youtube/rTSODCT4mKw)](https://youtu.be/M5t3AbLpxks) 16 | 17 | ### Часть 4. 18 | 19 | [![Топ вопросов на собеседовании по SQL - Часть 4](https://markdown-videos-api.jorgenkh.no/youtube/XKg7bR5ksFg)](https://youtu.be/XKg7bR5ksFg) 20 | 21 | ### Часть 5. 22 | 23 | [![Топ вопросов на собеседовании по SQL - Часть 5](https://markdown-videos-api.jorgenkh.no/youtube/XKg7bR5ksFg)](https://youtu.be/VHZQQr47Z90) 24 | 25 | ## Вопросы по SQL. 26 | 27 | 1. В каком порядке выполняется запрос и кратко охарактеризуй каждый оператор: 28 | 29 | ``` 30 | SELECT 31 | t1.col_2 32 | , COUNT(*) 33 | , COUNT(*) OVER() 34 | FROM Table_1 AS t1 35 | INNER JOIN Table_2 AS t2 36 | ON t1.id =t2.id 37 | WHERE 1 = 1 AND 38 | t1.col_1 > 2 39 | GROUP BY 40 | t1.col_1 41 | HAVING 42 | COUNT(*) > 1 43 | QUALIFY 44 | COUNT(*) OVER() > 1 45 | ORDER BY 2 46 | LIMIT 1 47 | ``` 48 | 2. Какие виды команд ты знаешь? Назови примеры команд каждого вида и их задачу. 49 | 3. Отличие DROP, DELETE, TRUNCATE. 50 | 4. Назови основные типы данных в SQL. За основу возьми любую БД. 51 | 5. Назови "нестандартные" типы данных, которые ты знаешь. 52 | 6. Различие строковых типов данных CHAR, VARCHAR, TEXT. 53 | 7. Назовите логические виды JOIN и для чего они нужны. 54 | 8. Назовите физические виды JOIN и их принцип работы. 55 | 9. Как определить, что функция является оконной? 56 | 10. Назови виды оконных функций. 57 | 11. В чем разница между RANK и DENSE_RANK? 58 | 12. Как определяется окно строк в оконной функции? Объясни, как понимаешь принцип работы оконной функции. 59 | 13. Как применял оконные функции на практике? Расскажи пример из жизни. (Если такого примера нет, посмотри "Алгоритм поиска" (Сделай пост на данную тему и не забудь вставить ссылку на него)). 60 | 14. Как ты понимаешь, для чего нужно оптимизировать запросы? 61 | 15. В чем различия команд EXPLAIN и EXPLAIN ANALYZE? 62 | 16. Расскажи алгоритм того, как бы ты оптимизировал запрос. 63 | 17. Что делают команды VACUUM, ANALYZE и VACUUM ANALYZE? 64 | 18. Что такое spill таблиц? 65 | 19. Что выведет следующая команда: 66 | 67 | ``` 68 | SELECT NULL + 5, 69 | 5 - NULL, 70 | 10 * NULL, 71 | 10 / NULL, 72 | NULL / 10, 73 | NULL || 'какая-то прикольная фраза' 74 | ``` 75 | 76 | 20. В чем различие команд COUNT(*) и COUNT(<имя колонки>)? 77 | 21. Как посчитать среднее значение? (Вопрос с подвохом) 78 | 22. Какими конструкциями дополняется ORDER BY, чтобы значения NULL стояли в начале и в конце таблицы? 79 | 23. Как избавиться от NULL-значений? Как ввести ограничение на вставку NULL-значений в таблице? 80 | 24. Как разделить значение на 0, чтобы получить в ответе NULL? 81 | 25. Чем отличаются COUNT(*), COUNT(1), COUNT('a')? 82 | 26. В чем отличие между группировкой и оконной функцией? 83 | 27. Чем отличаются результаты запросов: 84 | 85 | ``` 86 | SELECT col1, COUNT(*) 87 | FROM t1 88 | GROUP BY col1; 89 | ``` 90 | 91 | ``` 92 | SELECT DISTINCT col1, COUNT(*) OVER(PARTITION BY col2) 93 | FROM t1 94 | ``` 95 | 96 | 28. Есть 2 таблицы: в первой 10 строк, во второй 100 строк. Назови максимальное и минимальное количество возвращаемых строк при разных видах JOIN. (Данные могут быть любые.) 97 | 29. Есть 2 таблицы: в первой 10 строк, во второй 100 строк. Назови максимальное и минимальное количество возвращаемых строк при разных видах JOIN. (Без NULL-значений и индексы не повторяются в рамках одной таблицы, т.е. в двух таблицах данные могут как повторяться, так и нет.) 98 | 30. В таблице 100 млн строк, необходимо удалить 90 млн. Как ты это сделаешь и почему? 99 | 31. Является ли следующая команда транзакцией? 100 | 101 | ``` 102 | SELECT * FROM t1 WHERE id > 5; 103 | ``` 104 | 32. Есть запрос, который работает ночью и строит отчет. Ежедневно он работал нормально и создавал отчет за 2 часа. Сегодня утром ты пришел на работу, а отчета нет. Смотришь свой пайплайн, а он все еще крутится на чтении запроса. Что могло произойти? 105 | 33. Как быстро посчитать количество строк в таблице, имеющей нормальную структуру, например, в 3 НФ, где много колонок и пусть в ней даже JSON'овский сырец хранится? Структура таблицы пусть будет следующая: 106 | 107 | ``` 108 | CREATE TABLE t1 109 | ( 110 | id int primary key, 111 | col1 text, 112 | FK_id int NOT NULL, 113 | col2 text, 114 | col3 text, 115 | .... 116 | col100 jsonb 117 | ) 118 | ``` 119 | 34. Что такое и для чего нужен подзапрос? Что такое коррелируемый и не коррелируемый подзапрос? В чем отличиие СТЕ от подзапроса? 120 | 35. Для чего нужна временная таблица, если есть CTE? 121 | 36. Для чего нужна команда UNION и в чем её различие с UNION ALL? Какая команда работает быстрее и почему? Какие еще операции над множествами ты знаешь и что они делают? 122 | 37. Расскажи про условия в SQL. Для чего нужна конструкция CASE, как она записывается и в каких конструкциях запроса её можно использовать? 123 | 38. Различие между конструкциями WHERE, HAVING, QUALIFY? 124 | 39. С помощью каких команд выдается права доступа? 125 | 40. Чем отличаются типы данных JSON и JSONb? 126 | 41. Что будет делать, если в плане запроса увидели Nested Loop? 127 | 42. Как эффективно удалить дубликаты строк в большой таблице? 128 | 43. Для чего нужна контрукция constraints? -------------------------------------------------------------------------------- /Resume/README.md: -------------------------------------------------------------------------------- 1 | # Резюме 2 | 3 | - [Резюме](#резюме) 4 | - [Стажировка](#стажировка) 5 | - [Как составить резюме?](#как-составить-резюме) 6 | - [Примеры описания опыта](#примеры-описания-опыта) 7 | 8 | *** 9 | 10 | **Вопрос:** Где взять опыт работы если без него не берут?\ 11 | **Ответ:** Адаптировать 12 | 13 |

14 | 15 |

16 | 17 | > Чтобы попасть на тех собес, вам нужно пройти автофильтры рекрутеров по годам опыта. Важно, чтобы в вашем резюме была проставлена именно правильная цифра. Стажировок для НЕ СТУДЕНТОВ мало. Есть конечно компании, которые вас нанимают стажером или джуном, но перепродают большим бигтехам, как сеньера. Разницу естественно забирают себе. Справедливо ли это - решать вам. Мне такой подход не нравится. 18 | 19 | ### Стажировка 20 |

21 | 22 |

23 | 24 | Если вы студент, то можете во время учебы запрыгнуть на SberSeasons. В целом норм вариант пока вы учитесь. Там прям берут студентов последних курсов технических университетов. 25 | 26 | Если вы закончили универ вчера или 100 лет назад, то для вас СТАЖИРОВОК немного. Платить там могут до 100к. Если вам надо жить в Москве, у вас семеро детй и четверо козлят - возможно зарплаты в 60к вам не хватит. Здесь я рекомендую сразу идти на junior или junior+. 27 | 28 | И по деньгам это будет от 120к на руки. Хотя у меня лично есть примеры, когда люди залетали сразу на мидла на 200к на руки. Нужны будут пруфы - пиши мне в телегу. 29 | 30 | *** 31 | 32 | ### Как составить резюме? 33 | 34 | [Большая часть материала взята из этого источника](https://t.me/lavka_og/18) 35 | 36 | > *Советы универсальные, но часть заточена под платформу Head Hunter* 37 | 38 | **Базированная База** 39 | - **Резюме нужно, чтобы "продать" себя нанимающей стороне и у них не осталось вопросов, почему ТЕБЯ должны взять на это место.** 40 | 41 | **Сделай PDF** 42 | - У тебя всегда должно быть 2 резюме, одно на платформе поиске работы, а другое - сохраненное в PDF файл, которое будешь отправлять по запросу (например в телеге). 43 | 44 | **Шапка** 45 | - Заполняй ФИО, свой город, контакты 46 | - Рядом с номером телефона в комментарии укажи свой ТГ (для XX - больше вероятность, что напишут напрямую) 47 | - Городом указывай - Москва или Питер. Только если не нужен конкретный регион или работа в местном офисе 48 | - Возраст - если уже победил кризис среднего возраста или еще бывший школьник, то возраст не указывай. Эйджизм дело такое... 49 | - Поставь нормальное "живое" фото, примерно, как на паспорт. Если ты на нем улыбаешься, вообще замечательно. Никаких фото с клуба с бутылочкой 🍾 минералки в руке. 50 | Нет нормального фото, тогда не ставь. Если ты школьник, тоже не ставь 51 | - Должность пиши, как в большинстве вакансий для твоего стека (Python Developer). Грейд нигде тоже не указывай, если только не претендуешь на Лида и выше. Никаких Middle Питон Девелопер, вот как на ХХ написано, так и пиши 52 | - Не указывай ЗП, могут предложить больше чем ты хотел изначально. Исключение - отсечение по нижней границе для синьоров с опытом и ЗП 400к+ 53 | 54 | **Опыт работы** 55 | 56 | 57 | >❗️ ВАЖНО ДЛЯ ТЕХ КТО РАБОТАЕТ ПО СЗ, ГПХ, ИП или служит по контракту (военный). 58 | В этих случаях подтвердить опыт работы документально будет проблематично. У вас есть два варианта решения проблемы: Написать Study | Pet Project или ООО "Рога и Копыта" или ООО "Связь" (для военных). 59 | 60 | Толковых ребят с военки реально много, и к сожалению никого не волнует, что вы защищали свою Родину, а теперь у вас нет записи в выписке из Трудовой книжке. 61 | 62 | Я не против, если вы сделаете себе резюме сразу на Middle-Senior. Походите на собесы. Задачи собеседующих проверить ваши компетенции. Можете просто даже протестировать рынок и понять, насколько много или мало надо знать на такие деньги. В случае, если вы успешно пройдете собес и получите оффер на 350к с ходу, я могу либо поздравить вас с отличными навыками, либо поругать тим лида с той стороны, который плохо вас прособеседовал. Ведь к собесу надо готовиться не только кандидату, но и собеседующей стороне! 63 | 64 | Важный момент. Если вы с ходу получили оффер на хорошие деньги, взвесьте все ЗА и ПРОТИВ перед соглашением. Если у вас нет реального опыта, то будет очень тяжело. Оптимально идти все-таки на начальные или средние позиции в крупные компании, где медленные процессы, чтобы было время освоиться. 65 | 66 | **Года опыта** 67 | 68 | - Пишите **2 года опыта** на текущем месте работы (даже если вы пожарный или медсестра). Можно написать Study | Pet Project (в целом это проходит фильтры HR и вам могут писать рекрутеры САМИ). Но эффективнее, если опыт будет адаптирован. **Забудьте** про всю свою предыдущую жизнь. На крайнем месте работы вам удалось переключиться на задачи, связанные с данными. Позиции дата инженера/аналитика у компании не было, так как это были нецелевые задачи компании. Вы автоматизировали сбор данных и наладили дашборд для руководства. Вам так это понравилось, что вы решили свичнуться в DE и начать работать с реальной Big Data. Вы сочиняете себе легенду. 69 | 70 | - Легенда является легендой только в рамках того, что это была реальная задача в компании. Вам реально надо собрать проект по типу [HallatapeETLPipeline](https://github.com/halltape/HalltapeETL) и по возможности адаптировать идею под свой род деятельности. На собесе проверяют глубину знания инструмента и степень его владения, а не качество выполняемой работы на предыдущем месте. 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
Пример легенды
Работал аналитиком (по факту монтажником). Написал телеграм бота, который собирал данные по расходникам с каждого объекта и складывал все в СУБД PostgreSQL. Все было развернуто в Docker на сервере и каждый вечер, неделю, месяц Airflow читал данные из базы данных и внутри pandas или pyspark строили витрины отчеты для руководства
79 | 80 | - Описывайте свой опыт с указанием всех ключевых слов 81 | 82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
Настроил парсинг и загрузку данных в хранилище
Настроил парсинг данных из API с помощью pandas и request, а также загрузку в Clickhouse при помощи Airflow + настроил DAG мониторинга данных с помощью dbt
92 | 93 | >❗️ Удаляйте весь **НЕРЕЛЕВАНТНЫЙ** опыт. Даже, если у вас за плечами **10-20 лет** спасения жизни человечества или продажи галстуков в пустыне – это никак не поможет в поиске работы Дата Инженера. Мы не спасаем мир и не продаем галстуки. Только работа с данными.\ 94 | >❗️❗️ Крутить можно и больше. Вопрос только в том, насколько вы готовы за это брать ответственность. На 2-3 года накрученного опыта вас будут спрашивать конкретные кейсы (примеры решенных задач). Я рекомендую идти либо на джуна, либо на джун+. Через год вы станете уже мидлом и сможете мощно заявлять любые шестизначные суммы. 95 | 96 | 97 | **Образование** 98 | - Указываем обязательно, если оно есть, хоть какое-то. Особенно высшее. Даже не оконченное и не ИТ-шное. Показывает, что человек обучаем и не совсем "улиточка" 🐌 99 | 100 | **Языки** 101 | - Пиши все которые знаешь. Уровень указывай, как чувствуешь, но чем выше тем лучше 102 | 103 | **Стажировки** 104 | - Никаких стажировок указывать не надо. Так же не пиши, что ничего не знаешь и "готов работать за еду, только возьмите меня" 105 | 106 | **Курсы** 107 | - Курсы не пишем, особенно те, что у всех на слуху. Исключение - курсы повышение квалификации которые котируются именно в твой области и их наличие показатель для нанимающей стороны. 108 | 109 | **Навыки** 110 | - На ХХ (HeadHunter) можно указать навыки в количестве 30 штук. Указывай все, что он предлагает для твоего стека и с чем ты работал. "Стрессоустойчивость" и "работу в команде" и похожее указывать не нужно. 111 | Если делаешь шаблон сам, то можешь сделать отдельный блок Скиллы\Skills 112 | 113 | **Программист-водитель** 114 | - Никаких прав "Категории - В" указывать не нужно. ХХ любит добавлять их самостоятельно, проверяем и убираем 115 | 116 | **Рекомендации** 117 | - Убираем. Если это не знаковая фигура, которую все знают или известна в твоей области 118 | 119 | **О себе** 120 | - Обязательно надо оставить **контактную информацию** в самом конце (пример ниже). Вам будут больше писать, открытие контактов в **HH** платное. 121 | 122 | Для связи:\ 123 | ТГ - @ilon_mask\ 124 | почта - IlonMask@om.nom\ 125 | телефон - 8 (800) 555-35-35\ 126 | *проще позвонить, чем у кого-то занимать* 127 | 128 | **🏁 Финально** 129 | - Размер резюме должен быть такой, чтобы читающий понял, что ты нужный им человек. При этом не устал читать и не закрыл его. 130 | Для ХХ при экспорте в PDF размер не более 2 страниц А4, максимум 3. 131 | Для своей PDF - в идеале 1 страница, для разработчиков с опытом - 2. 132 | - Твое резюме должно быть минимум на трех сайтах: 133 | 134 | 135 | 136 | 137 | 138 | 139 |
HH.ruLinkedinХабр Карьера
140 | 141 | *** 142 | ### Примеры описания опыта 143 | *Кради, как художник* 144 | 145 |
146 |
147 | 148 |
149 | 150 |
151 | 152 |
153 | 154 |
155 | 156 |

157 | 158 | -------------------------------------------------------------------------------- /SPARK/ADVANCED/ARCHITECTURE/README.md: -------------------------------------------------------------------------------- 1 | ## Куратор раздела 2 | 3 | 4 | 5 | **Подвальный Артем**, 6 | _Data Engineer/Data Scientist_ 7 | 8 | [Канал Data Engineer Lab](https://t.me/dataengineerlab) 9 | 10 | Хочешь перейти в дата-инженерию, но не знаешь с чего начать? Пиши - составим резюме, продумаем твое развитие [https://t.me/ampodvalniy](https://t.me/ampodvalniy) 11 | 12 | 13 | Хочешь улучшить текущий раздел, внести недостающее или поправить формулировку? Предлагай PR и тегай [@Artemlin6231](https://github.com/Artemlin6231) 14 | 15 | ## Немного об этой главе 16 | Apache spark - это распределенный фреймворк обработки данных, ставший де-факто стандартом в обработке больших данных. Требуется практически повсевместо в работе дата-инженера. 17 | 18 | Приятного изучения) 19 | 20 | # Основы Apache Spark и RDD 21 | 22 | ## Введение 23 | 24 | **Apache Spark** — это масштабируемая платформа для распределённой обработки данных, которая позволяет выполнять вычисления в памяти, обеспечивая высокую производительность и гибкость. Она подходит как для пакетной (batch), так и для потоковой (streaming) обработки данных. 25 | 26 | --- 27 | 28 | ## Ключевые идеи Apache Spark 29 | 30 | - **Эффективная DAG-модель вычислений** 31 | Spark строит направленный ациклический граф (DAG), отображающий зависимости между этапами обработки. Это обеспечивает более гибкое и оптимизированное планирование по сравнению с классическим MapReduce. 32 | 33 | - **Ленивая модель исполнения** 34 | Преобразования не выполняются сразу. Spark откладывает их выполнение до вызова операции-действия, что позволяет эффективно планировать и объединять задачи. 35 | 36 | - **Гибкое управление памятью** 37 | - Предпочтение хранения данных в памяти 38 | - Сброс данных на диск при нехватке ресурсов 39 | - Возможность комбинированного хранения 40 | - Поддержка различных форматов сериализации 41 | 42 | - **Широкая поддержка языков** 43 | Поддерживаются API для **Scala**, **Java**, **Python** и **R** 44 | 45 | - **Единый API для batch и streaming обработки** 46 | 47 | --- 48 | 49 | ## RDD (Resilient Distributed Dataset) 50 | 51 | **RDD** — основная абстракция данных в Spark, представляющая собой неизменяемую, распределённую коллекцию объектов. 52 | 53 | ### Основные свойства RDD: 54 | 55 | - **Неизменяемость и отказоустойчивость (fault tolerance)** 56 | Все операции над RDD являются детерминированными и безопасными к сбоям. 57 | 58 | - **Два типа операций:** 59 | - **Transformations** — возвращают новый RDD, операции ленивые 60 | Примеры: `map`, `filter`, `join` 61 | - **Actions** — инициируют выполнение вычислений 62 | Примеры: `count`, `collect`, `save` 63 | 64 | - **Партиционирование** 65 | Данные разбиты на независимые части (partition), которые обрабатываются параллельно. 66 | 67 | - **Кэширование данных** 68 | Поддерживаются различные уровни хранения: 69 | - `memory` 70 | - `disk` 71 | - `memory & disk` 72 | - `external*` (при внешней настройке) 73 | 74 | 75 | ## Архитектура и модель вычислений Spark 76 | 77 |

78 | hadoop 79 |

80 | 81 | ### Компоненты архитектуры 82 | 83 | - **Driver Program** 84 | Главный управляющий процесс, с которого начинается выполнение приложения Spark. Он: 85 | - инициализирует `SparkContext`; 86 | - строит DAG вычислений; 87 | - управляет разбиением на задачи; 88 | - распределяет задачи по `executors`. 89 | 90 | - **SparkContext** 91 | Ядро взаимодействия приложения с кластером. Он: 92 | - подключается к `Cluster Manager`; 93 | - планирует вычисления; 94 | - отслеживает выполнение задач и собирает результаты. 95 | 96 | - **Cluster Manager** 97 | Менеджер ресурсов, который: 98 | - отслеживает доступные ресурсы; 99 | - выделяет `worker`-узлы; 100 | - запускает `executors`. 101 | Поддерживаемые варианты: **Standalone**, **YARN**, **Kubernetes**, **Mesos**. 102 | 103 | - **Worker Node** 104 | Узел, на котором исполняются задачи Spark. Каждый узел может запускать один или несколько `executors`. 105 | 106 | - **Executor** 107 | Процесс, который: 108 | - исполняет задачи; 109 | - кэширует промежуточные данные; 110 | - взаимодействует с `driver` для отправки результатов. 111 | 112 | - **Task** 113 | Минимальная единица вычислений в Spark. Каждое преобразование над данными разбивается на множество `tasks`, которые распределяются между `executors`. 114 | 115 | - **Cache** 116 | Используется для хранения данных в памяти или на диске с целью ускорения повторных вычислений. 117 | 118 | --- 119 | 120 | ### Как работает модель вычислений Spark 121 | 122 | 1. Пользователь пишет Spark-программу с использованием `RDD`, `DataFrame` или `Dataset`. 123 | 2. Программа запускается, и `Driver` создаёт `SparkContext`. 124 | 3. Spark строит **DAG (направленный ациклический граф)** всех ленивых операций (`transformations`). 125 | 4. DAG разбивается на **этапы (stages)**, каждый из которых состоит из задач (`tasks`). 126 | 5. Через `Cluster Manager`, Spark запускает `executor`'ы на `worker`-узлах. 127 | 6. `Tasks` исполняются параллельно на `executors`. 128 | 7. Промежуточные данные могут кэшироваться. 129 | 8. После завершения все результаты собираются и возвращаются `Driver`-у. 130 | 131 | 132 | # Экосистема Apache Spark 133 | 134 | Apache Spark — представляет собой целую экосистему модулей, предоставляющую мощные средства для работы с данными в различных форматах и задачах: от SQL-запросов и машинного обучения до потоковой обработки и анализа графов. 135 | 136 |

137 | hadoop 138 |

139 | 140 | --- 141 | 142 | ## Архитектура уровней 143 | 144 | Экосистема Spark построена на **многоуровневой архитектуре**, где каждый уровень отвечает за свою часть функциональности. 145 | 146 | ### 1. Spark Core 147 | 148 | Базовый компонент Spark, реализующий: 149 | 150 | - Распределённое планирование и выполнение задач 151 | - Управление памятью 152 | - Отказоустойчивость 153 | - Модель RDD (Resilient Distributed Dataset) 154 | 155 | Все остальные компоненты построены поверх `Spark Core`. 156 | 157 | --- 158 | 159 | ### 2. DataFrame API 160 | 161 | Предоставляет более высокоуровневую абстракцию над RDD — **DataFrame** (табличное представление данных). Обеспечивает: 162 | 163 | - SQL-подобный синтаксис 164 | - Оптимизацию исполнения через **Catalyst Optimizer** 165 | - Поддержку различных источников данных через **Data Source API** 166 | 167 | --- 168 | 169 | ### 3. Библиотеки Spark 170 | 171 | На верхнем уровне располагаются модули для специализированных задач: 172 | 173 | | Модуль | Назначение | 174 | |--------|------------| 175 | | **Spark SQL** | Выполнение SQL-запросов, работа с таблицами, интеграция с Hive | 176 | | **Spark Streaming** | Обработка потоковых данных в реальном времени | 177 | | **MLlib** | Машинное обучение: классификация, регрессия, кластеризация и др. | 178 | | **GraphX** | Графовые вычисления и анализ социальных сетей | 179 | | **Packages** | Расширения и сторонние библиотеки, добавляемые через Spark Packages | 180 | 181 | --- 182 | 183 | ### 4. Data Source API 184 | 185 | Позволяет подключаться к множеству внешних источников данных: 186 | 187 | - **Hadoop / HDFS** 188 | - **Apache Hive** 189 | - **Apache HBase** 190 | - **PostgreSQL**, **MySQL** 191 | - **CSV**, **JSON**, **Parquet** 192 | - **Elasticsearch** и другие 193 | 194 | Spark автоматически оптимизирует чтение, запись и обработку данных из этих источников. 195 | 196 | 197 | --- 198 | 199 | ## Поддерживаемые языки 200 | 201 | Spark поддерживает API на нескольких языках: 202 | 203 | - **Scala** (родной язык для Spark) 204 | - **Java** 205 | - **Python (PySpark)** 206 | - **R (SparkR)** 207 | 208 | # DataFrame API и Catalyst Optimizer в Apache Spark 209 | 210 | --- 211 | 212 | ## Что такое DataFrame API? 213 | 214 | **DataFrame** — это одна из высокоуровневых абстракций в Apache Spark, представляющая собой распределённую коллекцию данных в виде таблицы (аналогично таблице в реляционной базе или датафрейму в Pandas/R). 215 | 216 | DataFrame API предоставляет удобные и декларативные средства работы с данными: 217 | 218 | - SQL-подобный синтаксис (`select`, `filter`, `groupBy` и т.д.) 219 | - Поддержка различных источников: JSON, CSV, Parquet, Hive, JDBC, и т.д. 220 | - Поддержка нескольких языков: Scala, Python (PySpark), Java, R 221 | - Интеграция с **Catalyst Optimizer** для автоматической оптимизации запросов 222 | 223 | --- 224 | 225 | ## Как работает Catalyst Optimizer? 226 | 227 | **Catalyst** — это движок оптимизации запросов в Spark SQL и DataFrame API. Он обеспечивает автоматическую трансформацию запросов в эффективные планы выполнения с учётом структуры данных и статистики. 228 | 229 |

230 | hadoop 231 |

232 | --- 233 | 234 | ### Этапы обработки запроса в Catalyst: 235 | 236 | 1. ### SQL или DataFrame запрос 237 | Пользователь пишет SQL-запрос или использует DataFrame API. 238 | 239 | 2. ### Unresolved Logical Plan 240 | Spark строит первоначальный **логический план**, который ещё не содержит информации о типах данных и таблицах. 241 | 242 | 3. ### Analysis 243 | С помощью **каталога** (catalog) Spark разрешает имена таблиц, столбцов и типов данных. Получается **разрешённый логический план** (`Logical Plan`). 244 | 245 | 4. ### Logical Optimization 246 | На этом этапе Spark применяет **правила оптимизации**, такие как: 247 | - удаление ненужных столбцов (projection pruning), 248 | - фильтрация как можно раньше (predicate pushdown), 249 | - переупорядочивание `joins`. 250 | 251 | Результат — **оптимизированный логический план** (`Optimized Logical Plan`). 252 | 253 | 5. ### Physical Planning 254 | Spark генерирует несколько вариантов **физического плана** — конкретных стратегий выполнения операций. 255 | 256 | 6. ### Cost Model 257 | Для выбора наилучшего плана Spark применяет **модель стоимости**, оценивая ресурсоёмкость каждого варианта. 258 | 259 | 7. ### Code Generation 260 | Выбранный физический план используется для **генерации Java/Scala кода**, который преобразуется в **RDD-процессы**. 261 | 262 | --- 263 | 264 | ## Преимущества Catalyst и DataFrame API 265 | 266 | | Преимущество | Описание | 267 | |-----------------------------|----------| 268 | | Высокая производительность | Благодаря автоматической оптимизации | 269 | | Упрощение разработки | SQL-подобный синтаксис, декларативный подход | 270 | | Поддержка многих форматов | CSV, Parquet, JSON, Hive, JDBC и др. | 271 | | Расширяемость | Поддержка пользовательских функций (UDF) и типов данных | 272 | | Совместимость | Интеграция с MLlib, GraphX, Streaming и др. | 273 | 274 | --- 275 | 276 | ## Заключение 277 | 278 | DataFrame API и движок Catalyst являются основой гибкости и производительности Spark. Они позволяют пользователям сосредоточиться на логике анализа данных, а оптимизация и исполнение остаются на стороне платформы. 279 | 280 | > _Spark SQL и DataFrame API дают декларативный уровень, а Catalyst автоматически превращает его в оптимальный код._ 281 | 282 | -------------------------------------------------------------------------------- /SPARK/ARCHITECTURE/README.md: -------------------------------------------------------------------------------- 1 | ## Куратор раздела 2 | 3 | 4 | 5 | **Подвальный Артем**, 6 | _Data Engineer/Data Scientist_ 7 | 8 | [Канал Data Engineer Lab](https://t.me/dataengineerlab) 9 | 10 | Хочешь перейти в дата-инженерию, но не знаешь с чего начать? Пиши - составим резюме, продумаем твое развитие [https://t.me/ampodvalniy](https://t.me/ampodvalniy) 11 | 12 | 13 | Хочешь улучшить текущий раздел, внести недостающее или поправить формулировку? Предлагай PR и тегай [@Artemlin6231](https://github.com/Artemlin6231) 14 | 15 | ## Немного об этой главе 16 | Apache spark - это распределенный фреймворк обработки данных, ставший де-факто стандартом в обработке больших данных. Требуется практически повсевместо в работе дата-инженера. 17 | 18 | Приятного изучения) 19 | 20 | # Основы Apache Spark и RDD 21 | 22 | ## Введение 23 | 24 | **Apache Spark** — это масштабируемая платформа для распределённой обработки данных, которая позволяет выполнять вычисления в памяти, обеспечивая высокую производительность и гибкость. Она подходит как для пакетной (batch), так и для потоковой (streaming) обработки данных. 25 | 26 | --- 27 | 28 | ## Ключевые идеи Apache Spark 29 | 30 | - **Эффективная DAG-модель вычислений** 31 | Spark строит направленный ациклический граф (DAG), отображающий зависимости между этапами обработки. Это обеспечивает более гибкое и оптимизированное планирование по сравнению с классическим MapReduce. 32 | 33 | - **Ленивая модель исполнения** 34 | Преобразования не выполняются сразу. Spark откладывает их выполнение до вызова операции-действия, что позволяет эффективно планировать и объединять задачи. 35 | 36 | - **Гибкое управление памятью** 37 | - Предпочтение хранения данных в памяти 38 | - Сброс данных на диск при нехватке ресурсов 39 | - Возможность комбинированного хранения 40 | - Поддержка различных форматов сериализации 41 | 42 | - **Широкая поддержка языков** 43 | Поддерживаются API для **Scala**, **Java**, **Python** и **R** 44 | 45 | - **Единый API для batch и streaming обработки** 46 | 47 | --- 48 | 49 | ## RDD (Resilient Distributed Dataset) 50 | 51 | **RDD** — основная абстракция данных в Spark, представляющая собой неизменяемую, распределённую коллекцию объектов. 52 | 53 | ### Основные свойства RDD: 54 | 55 | - **Неизменяемость и отказоустойчивость (fault tolerance)** 56 | Все операции над RDD являются детерминированными и безопасными к сбоям. 57 | 58 | - **Два типа операций:** 59 | - **Transformations** — возвращают новый RDD, операции ленивые 60 | Примеры: `map`, `filter`, `join` 61 | - **Actions** — инициируют выполнение вычислений 62 | Примеры: `count`, `collect`, `save` 63 | 64 | - **Партиционирование** 65 | Данные разбиты на независимые части (partition), которые обрабатываются параллельно. 66 | 67 | - **Кэширование данных** 68 | Поддерживаются различные уровни хранения: 69 | - `memory` 70 | - `disk` 71 | - `memory & disk` 72 | - `external*` (при внешней настройке) 73 | 74 | 75 | ## Архитектура и модель вычислений Spark 76 | 77 |

78 | hadoop 79 |

80 | 81 | ### Компоненты архитектуры 82 | 83 | - **Driver Program** 84 | Главный управляющий процесс, с которого начинается выполнение приложения Spark. Он: 85 | - инициализирует `SparkContext`; 86 | - строит DAG вычислений; 87 | - управляет разбиением на задачи; 88 | - распределяет задачи по `executors`. 89 | 90 | - **SparkContext** 91 | Ядро взаимодействия приложения с кластером. Он: 92 | - подключается к `Cluster Manager`; 93 | - планирует вычисления; 94 | - отслеживает выполнение задач и собирает результаты. 95 | 96 | - **Cluster Manager** 97 | Менеджер ресурсов, который: 98 | - отслеживает доступные ресурсы; 99 | - выделяет `worker`-узлы; 100 | - запускает `executors`. 101 | Поддерживаемые варианты: **Standalone**, **YARN**, **Kubernetes**, **Mesos**. 102 | 103 | - **Worker Node** 104 | Узел, на котором исполняются задачи Spark. Каждый узел может запускать один или несколько `executors`. 105 | 106 | - **Executor** 107 | Процесс, который: 108 | - исполняет задачи; 109 | - кэширует промежуточные данные; 110 | - взаимодействует с `driver` для отправки результатов. 111 | 112 | - **Task** 113 | Минимальная единица вычислений в Spark. Каждое преобразование над данными разбивается на множество `tasks`, которые распределяются между `executors`. 114 | 115 | - **Cache** 116 | Используется для хранения данных в памяти или на диске с целью ускорения повторных вычислений. 117 | 118 | --- 119 | 120 | ### Как работает модель вычислений Spark 121 | 122 | 1. Пользователь пишет Spark-программу с использованием `RDD`, `DataFrame` или `Dataset`. 123 | 2. Программа запускается, и `Driver` создаёт `SparkContext`. 124 | 3. Spark строит **DAG (направленный ациклический граф)** всех ленивых операций (`transformations`). 125 | 4. DAG разбивается на **этапы (stages)**, каждый из которых состоит из задач (`tasks`). 126 | 5. Через `Cluster Manager`, Spark запускает `executor`'ы на `worker`-узлах. 127 | 6. `Tasks` исполняются параллельно на `executors`. 128 | 7. Промежуточные данные могут кэшироваться. 129 | 8. После завершения все результаты собираются и возвращаются `Driver`-у. 130 | 131 | 132 | # Экосистема Apache Spark 133 | 134 | Apache Spark — представляет собой целую экосистему модулей, предоставляющую мощные средства для работы с данными в различных форматах и задачах: от SQL-запросов и машинного обучения до потоковой обработки и анализа графов. 135 | 136 |

137 | hadoop 138 |

139 | 140 | --- 141 | 142 | ## Архитектура уровней 143 | 144 | Экосистема Spark построена на **многоуровневой архитектуре**, где каждый уровень отвечает за свою часть функциональности. 145 | 146 | ### 1. Spark Core 147 | 148 | Базовый компонент Spark, реализующий: 149 | 150 | - Распределённое планирование и выполнение задач 151 | - Управление памятью 152 | - Отказоустойчивость 153 | - Модель RDD (Resilient Distributed Dataset) 154 | 155 | Все остальные компоненты построены поверх `Spark Core`. 156 | 157 | --- 158 | 159 | ### 2. DataFrame API 160 | 161 | Предоставляет более высокоуровневую абстракцию над RDD — **DataFrame** (табличное представление данных). Обеспечивает: 162 | 163 | - SQL-подобный синтаксис 164 | - Оптимизацию исполнения через **Catalyst Optimizer** 165 | - Поддержку различных источников данных через **Data Source API** 166 | 167 | --- 168 | 169 | ### 3. Библиотеки Spark 170 | 171 | На верхнем уровне располагаются модули для специализированных задач: 172 | 173 | | Модуль | Назначение | 174 | |--------|------------| 175 | | **Spark SQL** | Выполнение SQL-запросов, работа с таблицами, интеграция с Hive | 176 | | **Spark Streaming** | Обработка потоковых данных в реальном времени | 177 | | **MLlib** | Машинное обучение: классификация, регрессия, кластеризация и др. | 178 | | **GraphX** | Графовые вычисления и анализ социальных сетей | 179 | | **Packages** | Расширения и сторонние библиотеки, добавляемые через Spark Packages | 180 | 181 | --- 182 | 183 | ### 4. Data Source API 184 | 185 | Позволяет подключаться к множеству внешних источников данных: 186 | 187 | - **Hadoop / HDFS** 188 | - **Apache Hive** 189 | - **Apache HBase** 190 | - **PostgreSQL**, **MySQL** 191 | - **CSV**, **JSON**, **Parquet** 192 | - **Elasticsearch** и другие 193 | 194 | Spark автоматически оптимизирует чтение, запись и обработку данных из этих источников. 195 | 196 | 197 | --- 198 | 199 | ## Поддерживаемые языки 200 | 201 | Spark поддерживает API на нескольких языках: 202 | 203 | - **Scala** (родной язык для Spark) 204 | - **Java** 205 | - **Python (PySpark)** 206 | - **R (SparkR)** 207 | 208 | # DataFrame API и Catalyst Optimizer в Apache Spark 209 | 210 | --- 211 | 212 | ## Что такое DataFrame API? 213 | 214 | **DataFrame** — это одна из высокоуровневых абстракций в Apache Spark, представляющая собой распределённую коллекцию данных в виде таблицы (аналогично таблице в реляционной базе или датафрейму в Pandas/R). 215 | 216 | DataFrame API предоставляет удобные и декларативные средства работы с данными: 217 | 218 | - SQL-подобный синтаксис (`select`, `filter`, `groupBy` и т.д.) 219 | - Поддержка различных источников: JSON, CSV, Parquet, Hive, JDBC, и т.д. 220 | - Поддержка нескольких языков: Scala, Python (PySpark), Java, R 221 | - Интеграция с **Catalyst Optimizer** для автоматической оптимизации запросов 222 | 223 | --- 224 | 225 | ## Как работает Catalyst Optimizer? 226 | 227 | **Catalyst** — это движок оптимизации запросов в Spark SQL и DataFrame API. Он обеспечивает автоматическую трансформацию запросов в эффективные планы выполнения с учётом структуры данных и статистики. 228 | 229 |

230 | hadoop 231 |

232 | --- 233 | 234 | ### Этапы обработки запроса в Catalyst: 235 | 236 | 1. ### SQL или DataFrame запрос 237 | Пользователь пишет SQL-запрос или использует DataFrame API. 238 | 239 | 2. ### Unresolved Logical Plan 240 | Spark строит первоначальный **логический план**, который ещё не содержит информации о типах данных и таблицах. 241 | 242 | 3. ### Analysis 243 | С помощью **каталога** (catalog) Spark разрешает имена таблиц, столбцов и типов данных. Получается **разрешённый логический план** (`Logical Plan`). 244 | 245 | 4. ### Logical Optimization 246 | На этом этапе Spark применяет **правила оптимизации**, такие как: 247 | - удаление ненужных столбцов (projection pruning), 248 | - фильтрация как можно раньше (predicate pushdown), 249 | - переупорядочивание `joins`. 250 | 251 | Результат — **оптимизированный логический план** (`Optimized Logical Plan`). 252 | 253 | 5. ### Physical Planning 254 | Spark генерирует несколько вариантов **физического плана** — конкретных стратегий выполнения операций. 255 | 256 | 6. ### Cost Model 257 | Для выбора наилучшего плана Spark применяет **модель стоимости**, оценивая ресурсоёмкость каждого варианта. 258 | 259 | 7. ### Code Generation 260 | Выбранный физический план используется для **генерации Java/Scala кода**, который преобразуется в **RDD-процессы**. 261 | 262 | --- 263 | 264 | ## Преимущества Catalyst и DataFrame API 265 | 266 | | Преимущество | Описание | 267 | |-----------------------------|----------| 268 | | Высокая производительность | Благодаря автоматической оптимизации | 269 | | Упрощение разработки | SQL-подобный синтаксис, декларативный подход | 270 | | Поддержка многих форматов | CSV, Parquet, JSON, Hive, JDBC и др. | 271 | | Расширяемость | Поддержка пользовательских функций (UDF) и типов данных | 272 | | Совместимость | Интеграция с MLlib, GraphX, Streaming и др. | 273 | 274 | --- 275 | 276 | ## Заключение 277 | 278 | DataFrame API и движок Catalyst являются основой гибкости и производительности Spark. Они позволяют пользователям сосредоточиться на логике анализа данных, а оптимизация и исполнение остаются на стороне платформы. 279 | 280 | > _Spark SQL и DataFrame API дают декларативный уровень, а Catalyst автоматически превращает его в оптимальный код._ 281 | -------------------------------------------------------------------------------- /SPARK/BASE/README.md: -------------------------------------------------------------------------------- 1 | ## Куратор раздела 2 | 3 | 4 | 5 | **Виндюков Евгений**, 6 | _Data Engineer_ 7 | 8 | [Канал Я – Дата Инженер](https://t.me/halltape_data) 9 | 10 | Если нужна помощь в обучении или в составлении резюме – пиши [@halltape](https://t.me/halltape) 11 | 12 | 13 | Хочешь улучшить текущий раздел, внести недостающее или поправить формулировку? Предлагай PR и тегай [@halltape](https://github.com/halltape) 14 | 15 | 16 | # Что такое Spark? 17 | 18 |

19 | spark 20 |

21 | 22 | **Apache Spark** - это супер быстрый фреймворк. Нужен он для того, чтобы обрабатывать большие данные на огромных кластерах (нескольких серверах). Работает он до 100 раз быстрее, чем Hadoop MapReduce в памяти или в 10 раз быстрее, чем на диске. 23 | 24 | Визуально его код выглядит так, будто скрестили SQL и Python: 25 |

26 | spark 27 |

28 | 29 | *** 30 | 31 | ## Откуда может читать данные Apache Spark 32 | 33 | ### Файловые системы 34 | - **HDFS** 35 | - **S3** 36 | - **Локальная файловая система** 37 | - **Azure Blob Storage**, **ADLS** (Azure Data Lake Storage) 38 | - **Google Cloud Storage** 39 | 40 | ### Форматы файлов 41 | - **CSV** 42 | - **JSON** 43 | - **Parquet** 44 | - **ORC** 45 | - **Avro** 46 | - **Text** 47 | 48 | ### Базы данных и хранилища (через коннекторы) 49 | - **JDBC** (PostgreSQL, MySQL, MSSQL и другие базы) 50 | - **ClickHouse** 51 | - **Greenplum** 52 | - **Hive** 53 | - **HBase** 54 | - **Cassandra** 55 | - **MongoDB** 56 | - **Elasticsearch** 57 | 58 | ### Системы стриминга 59 | - **Kafka** 60 | - **Kinesis** (AWS) 61 | 62 | ### Другие источники через коннекторы и плагины 63 | 64 | - **Delta Lake** 65 | - **Iceberg** 66 | - **Hudi** 67 | - **Google BigQuery** 68 | 69 | 70 |

71 | spark 72 |

73 | и так далее... 74 | 75 | *** 76 | 77 | ## А в чем разница между Spark и Pandas? 78 |

79 | spark 80 |

81 | 82 | Внешне код на pandas и на spark действительно похожи. Но pandas работает на одной машине и иногда дата инженеры могут его использовать для обработки маленьких кусочков данных (например из API), когда данные помещаются в оперативную память одного компьютера. 83 | 84 | *** 85 | 86 | ## Где запускается Spark? 87 | 88 |

89 | spark 90 |

91 | 92 | На работе под вашу команду будет выделено некоторое кол-во серверов. Собственно это физически может быть несколько стоек с серверами. Именно на них и будет запускаться ваш Spark. В бигтехах (больших компаниях, типа Банки) вы можете пользоваться коммунальным кластером. Это значит, что помимо вас, эти ресурсами будут пользоваться несколько команд. Соответственно здесь надо будет грамотно рассчитывать используемые ресурсы серверов, чтобы дать считать свои данные и другим. Подробнее про ресурсы будет пониже. 93 | 94 | *** 95 | ## Из чего состоит Spark? 96 | 97 |

98 | spark 99 |

100 | 101 | 102 |

103 | spark 104 |

105 | 106 | 107 | 108 | Если очень просто, то для того, чтобы посчитать сборку витрины данных, вам нужно будет запустить Spark приложение с конкретным кол-вом CPU и RAM. Эти значения вы указываете самостоятельно. Очевидно, что если вы укажите слишком много, то это может занять весь КЛАСТЕР. Таким образом вы отберете ресурсы от других пользователей. Поэтому в Spark нужно уже начинать думать об этом заранее. 109 | *** 110 | 111 | ## Как Spark читает данные? 112 | 113 |

114 | spark 115 |

116 | 117 | Spark можно очень гибко настраивать, но по умолчанию он часто читает файл и разбивает его на кусочки (типа на 128Мб). Этот параметр может меняться в зависимости от источника, настроек системы и так далее. Возьмем вариант в 128Mb. 118 | 119 | **Исходные данные:** 120 | - Файл весом **10 Gb** 121 | - **8 серверов** (один сервер: 2 ядра CPU и 16Gb RAM) 122 | 123 | **В Spark:** 124 | - 1 ядро (core) может выполнять 1 задачу (task) одновременно. 125 | - Установим каждому executor’у 2 ядра, тогда он может одновременно обрабатывать 2 tasks. 126 | 127 | **ВАЖНО!** 128 | 129 | Мы можем вручную указать кол-во executors и выделяемое им кол-во CPU и RAM. 130 | Совершенно необязательно, что на одном сервере будет запускаться один executor. Если хватает CPU и RAM для двух и более, то запуститься сразу несколько. 131 | 132 |

133 | spark 134 |

135 | 136 | ``` 137 | Если Spark читает файл размером 10Gb, значит он поделит его на 138 | 10 * 1024 Mb / 128 Mb = 80 partitions 139 | ``` 140 | 141 | **Что получаем:** 142 | - Кластер может одновременно обрабатывать 16 tasks (8 серверов по 2 tasks). 143 | - Поскольку партций 80, Spark сначала запустит 16 задач параллельно (на 8 executors). 144 | - Как только один task завершается, на освободившемся ядре сразу стартует следующий task. 145 | - И так, пока все 80 партций не будут обработаны. 146 | 147 | Т.е. наш Spark уже при чтении разбил данные на небольшие кусочки и раскидал их по серверам, чтобы обработать их параллельно. Важный момент, что кол-во executors мы можем, как увеличить, так и уменьшить. Это позволяет напрямую влиять на скорость обработки данных. 148 | *** 149 | 150 | ## Что такое Shuffle? 151 |

152 | spark 153 |

154 | 155 | Shuffle происходит, когда Spark нужно перемешать данные между executor, например для выполнения операции JOIN и так далее. Представьте, что данные с одним и тем же ключем для join у вас лежат на разных executors. Очевидно, что нужно все перетасовать между собой. Более подробное объяснения можете почитать [тут](../ADVANCED/README.md#Shuffle-в-Spark) ! 156 | 157 | *** 158 | 159 | ## Сколько нужно выделять executors? 160 | 161 | Ниже небольшое объяснение, почему слишком большое или слишком маленькое кол-во executors не всегда хорошо. На практике, особенно на junior позициях, вам не придется сильно заморачиваться с расчетом ресурсов. Ваш TeamLead выдаст вам готовый конфиг с уже настроенными параметрами. Ваша задача будет только запустить его. Но если вас спросят об этом на собесе – это будет огромным плюсом! 162 | 163 |

164 | spark 165 |

166 | 167 |

168 | spark 169 |

170 | 171 | Ниже по ссылке можете посмотреть, как рассчитываются ресурсы для Spark приложения: 172 | - [Онлайн расчет ресурсов для Spark](https://sparkconfigoptimizer.com) 173 | 174 | *** 175 | 176 | ## На что расходуется память в Spark? 177 | 178 |

179 | spark 180 |

181 | 182 | Эта информация скорее для Advanced уровня и о ней почти не спрашивают на собесах. Это понадобится вам только в том случае, когда вы начнете вручную настраивать кол-во выделяемых ресурсов для executor и увидите, что ваши Gb на самом деле пилятся внутри Spark еще на много чего полезного. Условно, будто вы купили диск на 1Gb, а в реальности там оказалось только 500Мб полезной нагрузки. 183 | 184 | *** 185 | 186 | ## Есть ли у Spark UI? 187 | 188 | Да, у Spark есть интерфейс, где можно отслеживать план выполнения вашего запроса. Это реально удобная вещь. Визуально это выглядит вот так: 189 | 190 |

191 | spark 192 |

193 | 194 | Для того, чтобы разобраться еще и UI, ниже хорошая статья: 195 | - [Как пользоваться Spark UI?](https://habr.com/ru/companies/avito/articles/764996/) 196 | 197 | *** 198 | 199 | ## Где учить Spark? 200 | 201 | Одна из хороших практик для обучения - переписывать запросы с SQL на Spark и наоборот. 202 | Результаты, очевидно, должны быть одинаковыми. 203 | 204 | **Вот пример двух одинаковых запросов на SQL и на PySpark** 205 | 206 | ```sql 207 | SELECT 208 | d.department_name, 209 | AVG(s.salary) AS average_salary 210 | FROM employees e 211 | JOIN departments d ON e.department_id = d.department_id 212 | JOIN salaries s ON e.employee_id = s.employee_id 213 | WHERE s.salary >= 3000 214 | GROUP BY d.department_name 215 | ORDER BY average_salary DESC; 216 | ``` 217 | 218 | 219 | ```python 220 | result_df = employees_df\ 221 | .join(departments_df, "department_id")\ 222 | .join(salaries_df, "employee_id") 223 | .filter(salaries_df.salary >= 3000) 224 | .groupBy("department_name") 225 | .agg(F.avg("salary").alias("average_salary")) 226 | .orderBy(F.desc("average_salary")) 227 | result_df.show() 228 | ``` 229 | 230 | Также рекомендую порешать несколько задачек отсюда: 231 | 232 | ➜ [Leetcode по PySpark](https://platform.stratascratch.com/coding?code_type=6) 233 | 234 | Чтобы попробовать Spark локально, можно развернуть мини кластер у себя локально: 235 | 236 | ➜ [Разверни свой Spark кластер](https://github.com/halltape/HalltapeSparkCluster/tree/main) -------------------------------------------------------------------------------- /change_log: -------------------------------------------------------------------------------- 1 | Версия 2.1: 2 | 3 | - Добавлена новая инфа по Spark- Переписана полностью инфа по Hadoop 4 | - Добавлен новый автор Артем Подвальный - https://t.me/dataengineerlab 5 | - Добавлен контент по "Оптимизации запросов" и "Кейс оптимизации" по Greenplum 6 | - Разделены вопросы собеседований по темам 7 | - Добавлена новая часть видео "Вопросы собеседований по SQL - часть 5" 8 | - Добавлена новая часть видео "Вопросы собеседований по Базам Данных - часть 1" 9 | 10 | Версия 2.0: 11 | 12 | - Тут должно быть херова тьма пунков, но по сути тут самое начало создания Роадмапа, поэтому забиваем большой болт)))) -------------------------------------------------------------------------------- /files/Apache Airflow.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/files/Apache Airflow.pdf -------------------------------------------------------------------------------- /files/data_vault.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/files/data_vault.pdf -------------------------------------------------------------------------------- /files/deep_dive_hdfs_pdf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/files/deep_dive_hdfs_pdf.pdf -------------------------------------------------------------------------------- /files/greenplum.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/files/greenplum.pdf -------------------------------------------------------------------------------- /files/normal_tables.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/files/normal_tables.pdf -------------------------------------------------------------------------------- /png/Apache_Kafka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/Apache_Kafka.png -------------------------------------------------------------------------------- /png/BASH_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/BASH_logo.png -------------------------------------------------------------------------------- /png/CH_col_oriented.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/CH_col_oriented.jpg -------------------------------------------------------------------------------- /png/af_arfitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/af_arfitecture.png -------------------------------------------------------------------------------- /png/af_connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/af_connection.png -------------------------------------------------------------------------------- /png/af_dag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/af_dag.png -------------------------------------------------------------------------------- /png/af_final_task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/af_final_task.png -------------------------------------------------------------------------------- /png/af_start_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/af_start_page.png -------------------------------------------------------------------------------- /png/airflow_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/airflow_logo.jpg -------------------------------------------------------------------------------- /png/amp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/amp.jpg -------------------------------------------------------------------------------- /png/batch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/batch.png -------------------------------------------------------------------------------- /png/cases.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/cases.jpg -------------------------------------------------------------------------------- /png/ch_column_oriented.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_column_oriented.gif -------------------------------------------------------------------------------- /png/ch_filename.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_filename.jpg -------------------------------------------------------------------------------- /png/ch_filename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_filename.png -------------------------------------------------------------------------------- /png/ch_filename.png.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_filename.png.jpg -------------------------------------------------------------------------------- /png/ch_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_logo.jpg -------------------------------------------------------------------------------- /png/ch_mater_col.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_mater_col.png -------------------------------------------------------------------------------- /png/ch_merge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_merge.gif -------------------------------------------------------------------------------- /png/ch_minmax.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_minmax.jpg -------------------------------------------------------------------------------- /png/ch_minmax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_minmax.png -------------------------------------------------------------------------------- /png/ch_no_column.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_no_column.png -------------------------------------------------------------------------------- /png/ch_partition.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_partition.jpg -------------------------------------------------------------------------------- /png/ch_set_idx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_set_idx.jpg -------------------------------------------------------------------------------- /png/ch_table.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ch_table.jpg -------------------------------------------------------------------------------- /png/data_mart.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/data_mart.jpeg -------------------------------------------------------------------------------- /png/data_warehouse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/data_warehouse.png -------------------------------------------------------------------------------- /png/dbt_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/dbt_logo.png -------------------------------------------------------------------------------- /png/de1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/de1.jpg -------------------------------------------------------------------------------- /png/de1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/de1.png -------------------------------------------------------------------------------- /png/de2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/de2.png -------------------------------------------------------------------------------- /png/de3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/de3.png -------------------------------------------------------------------------------- /png/de4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/de4.png -------------------------------------------------------------------------------- /png/de5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/de5.png -------------------------------------------------------------------------------- /png/docker_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/docker_logo.png -------------------------------------------------------------------------------- /png/dv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/dv.png -------------------------------------------------------------------------------- /png/dwh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/dwh.png -------------------------------------------------------------------------------- /png/dwh_ai_acid_dirty_reading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/dwh_ai_acid_dirty_reading.png -------------------------------------------------------------------------------- /png/dwh_ai_acid_lost_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/dwh_ai_acid_lost_data.png -------------------------------------------------------------------------------- /png/dwh_ai_acid_non_repetitive_reading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/dwh_ai_acid_non_repetitive_reading.png -------------------------------------------------------------------------------- /png/dwh_ai_acid_phantom_reading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/dwh_ai_acid_phantom_reading.png -------------------------------------------------------------------------------- /png/exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/exp.png -------------------------------------------------------------------------------- /png/git_fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/git_fork.png -------------------------------------------------------------------------------- /png/git_fork2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/git_fork2.png -------------------------------------------------------------------------------- /png/git_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/git_github.png -------------------------------------------------------------------------------- /png/git_ssh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/git_ssh.png -------------------------------------------------------------------------------- /png/git_ssh2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/git_ssh2.png -------------------------------------------------------------------------------- /png/git_ssh3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/git_ssh3.png -------------------------------------------------------------------------------- /png/github_pics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/github_pics.jpg -------------------------------------------------------------------------------- /png/gp_advanced_mirrors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_advanced_mirrors.png -------------------------------------------------------------------------------- /png/gp_advanced_mirrors_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_advanced_mirrors_fail.png -------------------------------------------------------------------------------- /png/gp_ao_colum_orientir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_ao_colum_orientir.png -------------------------------------------------------------------------------- /png/gp_ao_string_orientir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_ao_string_orientir.png -------------------------------------------------------------------------------- /png/gp_ao_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_ao_table.png -------------------------------------------------------------------------------- /png/gp_arhitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_arhitecture.png -------------------------------------------------------------------------------- /png/gp_b_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_b_tree.png -------------------------------------------------------------------------------- /png/gp_distributed_broadcast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_distributed_broadcast.png -------------------------------------------------------------------------------- /png/gp_distributed_by_key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_distributed_by_key.png -------------------------------------------------------------------------------- /png/gp_distributed_random.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_distributed_random.png -------------------------------------------------------------------------------- /png/gp_explain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_explain.png -------------------------------------------------------------------------------- /png/gp_explain_analyze.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_explain_analyze.png -------------------------------------------------------------------------------- /png/gp_external_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_external_table.png -------------------------------------------------------------------------------- /png/gp_gpfgist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_gpfgist.png -------------------------------------------------------------------------------- /png/gp_group_mirrors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_group_mirrors.png -------------------------------------------------------------------------------- /png/gp_group_mirrors_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_group_mirrors_fail.png -------------------------------------------------------------------------------- /png/gp_heap_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_heap_table.png -------------------------------------------------------------------------------- /png/gp_inc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_inc.jpg -------------------------------------------------------------------------------- /png/gp_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_index.png -------------------------------------------------------------------------------- /png/gp_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_logo.png -------------------------------------------------------------------------------- /png/gp_master_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_master_fail.png -------------------------------------------------------------------------------- /png/gp_mirrors_master.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_mirrors_master.png -------------------------------------------------------------------------------- /png/gp_mpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_mpp.png -------------------------------------------------------------------------------- /png/gp_partitions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_partitions.png -------------------------------------------------------------------------------- /png/gp_partitions_comb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_partitions_comb.png -------------------------------------------------------------------------------- /png/gp_partitions_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_partitions_list.png -------------------------------------------------------------------------------- /png/gp_partitions_range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_partitions_range.png -------------------------------------------------------------------------------- /png/gp_pxf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_pxf.png -------------------------------------------------------------------------------- /png/gp_simple_load_save_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_simple_load_save_data.png -------------------------------------------------------------------------------- /png/gp_sql_operations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/gp_sql_operations.png -------------------------------------------------------------------------------- /png/hadoop_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/hadoop_arch.png -------------------------------------------------------------------------------- /png/hadoop_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/hadoop_logo.png -------------------------------------------------------------------------------- /png/hadoop_rep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/hadoop_rep.png -------------------------------------------------------------------------------- /png/hadoop_secondary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/hadoop_secondary.png -------------------------------------------------------------------------------- /png/halltape.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/halltape.jpg -------------------------------------------------------------------------------- /png/ind_part_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/ind_part_logo.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_bitmap1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_bitmap1.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_bitmap2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_bitmap2.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_bitmap3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_bitmap3.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_btree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_btree.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_btree_revers1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_btree_revers1.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_btree_revers2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_btree_revers2.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_clust_vs_non_clust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_clust_vs_non_clust.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_hash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_hash.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_part_bag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_part_bag.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/ind_part_three_bags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/ind_part_three_bags.png -------------------------------------------------------------------------------- /png/indexes_and_partitions/partitions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/indexes_and_partitions/partitions.png -------------------------------------------------------------------------------- /png/inmon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/inmon.png -------------------------------------------------------------------------------- /png/intern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/intern.png -------------------------------------------------------------------------------- /png/kafka_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/kafka_logo.png -------------------------------------------------------------------------------- /png/kafka_producers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/kafka_producers.png -------------------------------------------------------------------------------- /png/kappa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/kappa.png -------------------------------------------------------------------------------- /png/kimbal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/kimbal.png -------------------------------------------------------------------------------- /png/lakehouse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/lakehouse.png -------------------------------------------------------------------------------- /png/lambda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/lambda.png -------------------------------------------------------------------------------- /png/links.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/links.jpeg -------------------------------------------------------------------------------- /png/mail_pet_project.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/mail_pet_project.gif -------------------------------------------------------------------------------- /png/models_data.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/models_data.jpeg -------------------------------------------------------------------------------- /png/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/normal.jpg -------------------------------------------------------------------------------- /png/normal_table.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/normal_table.jpg -------------------------------------------------------------------------------- /png/olap_oltp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/olap_oltp.png -------------------------------------------------------------------------------- /png/pengwin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/pengwin.jpg -------------------------------------------------------------------------------- /png/pet_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/pet_project.png -------------------------------------------------------------------------------- /png/pp_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/pp_2.png -------------------------------------------------------------------------------- /png/que.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/que.jpg -------------------------------------------------------------------------------- /png/resume.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/resume.jpg -------------------------------------------------------------------------------- /png/shust.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/shust.jpg -------------------------------------------------------------------------------- /png/snowflake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/snowflake.png -------------------------------------------------------------------------------- /png/spark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark.png -------------------------------------------------------------------------------- /png/spark_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_arch.png -------------------------------------------------------------------------------- /png/spark_catalyst.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_catalyst.jpg -------------------------------------------------------------------------------- /png/spark_eco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_eco.png -------------------------------------------------------------------------------- /png/spark_images/SPARK.001.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.001.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.002.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.002.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.003.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.003.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.004.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.004.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.005.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.005.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.006.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.006.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.007.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.007.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.008.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.008.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.009.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.009.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.010.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.010.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.011.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.011.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.012.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.012.jpeg -------------------------------------------------------------------------------- /png/spark_images/SPARK.013.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/SPARK.013.jpeg -------------------------------------------------------------------------------- /png/spark_images/spark_ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_images/spark_ui.png -------------------------------------------------------------------------------- /png/spark_join.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_join.jpg -------------------------------------------------------------------------------- /png/spark_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_logo.png -------------------------------------------------------------------------------- /png/spark_stages.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/spark_stages.jpg -------------------------------------------------------------------------------- /png/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/star.png -------------------------------------------------------------------------------- /png/stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/stream.png -------------------------------------------------------------------------------- /png/yarn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/yarn.png -------------------------------------------------------------------------------- /png/yarn_eco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/yarn_eco.png -------------------------------------------------------------------------------- /png/yarn_map_reduce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halltape/HalltapeRoadmapDE/59cf92354171b7f0e00b9651c55014c4c95fa1d1/png/yarn_map_reduce.jpg --------------------------------------------------------------------------------