-
Notifications
You must be signed in to change notification settings - Fork 0
/
content.json
1 lines (1 loc) · 29.1 KB
/
content.json
1
{"pages":[{"title":"文章列表","text":"","link":"/archives/index.html"},{"title":"關於我","text":"建立部落格初衷一名轉職後的軟體工程師 上一份工作結束後,開始整理過往的工作筆記與心得,架設部落格原因如下: 紀錄所思、所學、所做,提醒自己不忘成為更好的模樣 一路成長的路上受到很多人的照顧,不管是網路上大神文章的分享抑或是生活中他人實作經驗的教導與分享都令人收穫良多,也希望回饋他人 藉由文章紀錄曾經實作過的想法與作品,別讓時間衝淡記憶導致未來開發必須再從頭來過 部落格定位主要寫寫實作上的經驗,偶爾會夾帶對於生活工作上的一些想法,等實際文章累積到一定數量再重新整理風格 工作經歷 四年資料工程/後端開發經驗 主力為Python,也利用Flask框架寫過網站,實作上搭配網頁開發三傑HTML、CSS、JavaScript 熟悉Requests與Scrapy爬蟲 參與並實作ML&DL專案 熟悉finereport視覺化 搭配VM與Docker建構服務 搭配MSSQL與MySQL資料庫 熟悉Git等開發工具 熟悉Crontab、Airflow等排程服務 部落格風格部落格風格參考HuliHexo的minos主題網路上分享的文章並不多,未來會以此部落格為模版寫一篇架構網站教學 文章聲明文章參考來源會附於文中或文末,若有任何轉載需求請來信:[email protected]","link":"/about/index.html"},{"title":"分類","text":"","link":"/categories/index.html"}],"posts":[{"title":"Airflow with docker compose (airflow+mysql+rabbitmq) 單機","text":"簡介 本篇針對docker-compose建構airflow+mysql+rabbitmq的環境 airflow基礎介紹與部署可參考: Airflow | 脚本东零西散?Airflow 快速搭建 pipeline(超详细) 主機環境 操作系统: Ubuntu 16.04.7 LTS 内核版本: Linux 4.15.0-142-generic docker-compose版本: v1.29.1 docker-compose.yml 官方docker-compose.yaml提供版本為airflow+redis+postgres,因此需修改docker-compose.yml內容 MySQL airflow支援版本為5.7、8 因最終希望建立可彈性擴展的airflow環境,官方推薦MySQL 8+ 設置MySQL帳戶密碼 若本機已安裝MySQL,需修改本機對應port 1234567891011121314151617181920mysql: image: mysql:8.0.27 # 下載MySQL版本為8+以上 ports: - \"3305:3306\" # 區別本機MySQL port,修改對應port:3305 environment: MYSQL_ROOT_PASSWORD: a12345 # MySQL root帳密 MYSQL_USER: airflow # airflow 於DB中的帳號 MYSQL_PASSWORD: worker # airflow 於DB中的密碼 MYSQL_DATABASE: airflow # airflow 設定檔存放的DB名稱 command: [\"mysqld\",\"--default-authentication-plugin=mysql_native_password\",\"--collation-server=utf8mb4_general_ci\",\"--character-set-server=utf8mb4\"] volumes: - /app/mysqldata8:/var/lib/mysql # MySQL數據 - /app/my.cnf:/etc/my.cnf # MySQL設定檔 healthcheck: test: mysql --user=$$MYSQL_USER --password=$$MYSQL_PASSWORD -e 'SHOW DATABASES;' # healthcheck command interval: 5s retries: 5 restart: always cap_add: - SYS_NICE rabbitmq image下載management版本,可看監控畫面 123456789101112131415rabbitmq: image: rabbitmq:3-management-alpine environment: - RABBITMQ_DEFAULT_USER=worker # rabbitmq的使用者帳戶 - RABBITMQ_DEFAULT_PASS=worker # rabbitmq的使用者密碼 ports: - \"5672:5672\" # container 對應port - \"15672:15672\" # 監控畫面port healthcheck: test: rabbitmq-diagnostics -q ping interval: 5s timeout: 30s retries: 50 restart: always worker 設定host_name,以便於flower中辨別worker 123456789101112131415161718192021airflow-worker: <<: *airflow-common hostname: host-01 # 設定host_name command: celery worker healthcheck: test: - \"CMD-SHELL\" - 'celery --app airflow.executors.celery_executor.app inspect ping -d \"celery@$${HOSTNAME}\"' interval: 10s timeout: 10s retries: 5 environment: <<: *airflow-common-env # Required to handle warm shutdown of the celery workers properly # See https://airflow.apache.org/docs/docker-stack/entrypoint.html#signal-propagation DUMB_INIT_SETSID: \"0\" restart: always depends_on: <<: *airflow-common-depends-on airflow-init: condition: service_completed_successfully x-airflow-common 環境 image下載版本2.0以上,本範例選擇airflow2.2.3 變更sevice連接方式 變更sevice建置名稱 123456789101112131415161718192021222324252627282930313233x-airflow-common: &airflow-common # In order to add custom dependencies or upgrade provider packages you can use your extended image. # Comment the image line, place your Dockerfile in the directory where you placed the docker-compose.yaml # and uncomment the \"build\" line below, Then run `docker-compose build` to build the images. image: ${AIRFLOW_IMAGE_NAME:-apache/airflow:2.2.3} # build: . environment: &airflow-common-env AIRFLOW__CORE__EXECUTOR: CeleryExecutor AIRFLOW__CORE__SQL_ALCHEMY_CONN: mysql+mysqldb://airflow:worker@mysql/airflow # 變更為mysql連線方式 AIRFLOW__CELERY__RESULT_BACKEND: db+mysql://airflow:worker@mysql/airflow # 變更為mysql連線方式 AIRFLOW__CELERY__BROKER_URL: amqp://worker:worker@rabbitmq:5672// # 變更為rabbitmq連線方式 AIRFLOW__CORE__FERNET_KEY: '' AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION: 'true' AIRFLOW__CORE__LOAD_EXAMPLES: 'true' AIRFLOW__API__AUTH_BACKEND: 'airflow.api.auth.backend.basic_auth' _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-} AIRFLOW__CORE__PARALLELISM: 64 AIRFLOW__CORE__DAG_CONCURRENCY: 32 AIRFLOW__SCHEDULER__PARSING_PROCESSES: 4 volumes: - ./dags:/opt/airflow/dags - ./logs:/opt/airflow/logs - ./plugins:/opt/airflow/plugins user: \"${AIRFLOW_UID:-50000}:0\" depends_on: &airflow-common-depends-on rabbitmq: # 設置rabbitmq service名稱 condition: service_healthy mysql: # 設置mysql service名稱 condition: service_healthy 設定本機對應container目錄12$ mkdir ./dags ./logs $ mkdir ./plugins # 自定義套件 設定airflow權限 確保AIRFLOW_UID為一般用戶UID 確保用戶擁有對應container目錄權限 1$ echo -e \"AIRFLOW_UID=$(id -u)\" > .env 啟動docker-compose12$ docker-compose up airflow-init # 初始化服務,確保container連結正常$ docker-compose up -d # 於背景執行中創建airflow container 啟動後畫面 container status: healthy 當container status為unhealthy,可參照docker logs <containerID> 修改bugs 完整docker-compose.yml可參考https://github.com/Dawn0472/docker-airflow/tree/main/單機 參考來源 Airflow 官網 Airflow 2.2.3 容器化安装 docker-compose healthcheck for rabbitMQ","link":"/articles/2022/06/07/Airflow-with-docker-compose-airflow-mysql-rabbitmq-%E5%96%AE%E6%A9%9F/"},{"title":"【爬蟲基礎介紹】part2: HTTP架構","text":"從上篇文章中我們可以瞭解 爬蟲的本質是要模擬人類瀏覽網頁的行為 實際我們在瀏覽網頁時,瀏覽器與伺服器之間如何傳遞訊息 若對上一篇文章有興趣,可參考【爬蟲基礎介紹】part1: 什麼是爬蟲? 爬蟲的本質是模擬人類瀏覽網頁的行為,人類操作瀏覽器瀏覽網頁,也就是最終程式需要模擬瀏覽器與伺服器互動,不被發現偽裝,才能成功完成擷取數據的過程。因此我們需要瞭解瀏覽器與伺服器如何互動 本篇文章會更深入說明,瀏覽器與伺服器在互動時的角色與行為規範 request與response如同part1文章所述,我們想知道博客來2021年度百大暢銷榜有哪些書? 博客來2021年度百大暢銷榜 當我們點擊博客來的網頁時,有四個專有名詞需要瞭解 客戶端(Client):連網設備、瀏覽器,會發送 請求 (request) 到Server 伺服器端(Server):收到Client發送的request,開始處理請求,並 回應 (response) 到Client 請求資料(request):Client向Server 索取資料 的行為 回應資料(response):Server 回傳資料 到Client的行為 我們可以先想像在Client與Server間有個郵差協助彼此互相傳遞消息,請求必有回應,最後資料呈現於網頁上,如下圖: HTTP協議引用維基百科說明 request-response: 電腦在電腦網路中用來相互通信的基本方法 而網路通訊的規範基礎即HTTP協議,也就是超文本傳輸協定 就像是寫信時,必須要有特定的信封,收件人必須要寫在中間,信封左右或上下寫上寄件人與收件人的地址,郵差才能迅速無誤幫我們寄出信件一樣,網路傳輸時需要遵守特定的規範,才能讓Client與Server之間能看懂訊號,並回傳正確的數據。 不知道大家是否曾經在瀏覽網頁時收到以下畫面無論是無法找到IP位置,或者是網頁回應時間過長無法連線等等訊息,都是告訴你現在網頁無法連線 如何透過HTTP得知現在網頁是否連線成功? 若無法連線是什麼原因造成?可以透過 HTTP狀態碼(HTTP Status Code) HTTP 狀態碼以數字表示,通常以開頭的數字可以判斷連線狀況一般成功連上網頁的Status Code為200,更多可參考A. MDN技術文件B. 常見與不常見的 HTTP Status Code(有趣的說明) 1XX : 臨時訊息提示,通常代表請求被接受,可繼續請求 2XX : 請求成功,常見代碼為200 3XX : 網頁重新導向,常見代碼為302,用戶需要採取進一步的行動才能完成請求 4XX : 客戶端錯誤,常見代碼為404,找不到伺服器位置(網址打錯之類) 5XX : 伺服器遇到錯誤,無法完成請求,常見代碼為504,Gateway Time-out 如何讓瀏覽器與伺服器溝通良好呢? 需透過一些額外資料的設定,這些設定稱為 HTTP 表頭(HTTP headers) 一般在爬蟲程式,我們只討論Request headers,更多可參考維基百科 常用到的headers Cookie : Server傳送予使用者瀏覽器的一個小片段資料,可追蹤記錄並分析使用者行為 User-Agent : Server從用戶的軟體規格、瀏覽器類別、版本號…等識別請求的Client為手機、電腦或平板,從而選擇適當的內容回應 Content-Type : Server回傳的內容格式 Referer : 當前網頁的上一頁從哪裡來 Host : Server主機位置 如何向瀏覽器請求資料? HTTP定義幾種標準方法可以向網址(URL)執行特定操作的請求方法一般常見的兩種為GET & POST,關於兩者差別,更詳細可參考表單中的 GET 與 POST 有什麼差別? GET: 向Server取得資料,所有提交的數據都顯示在 URL(網址) 上 舉例:單純向Server取得文字、圖片等資訊 POST: 向Server新增/提交數據,數據被包在message-body內 舉例:網頁登入會員資訊 其他Request Method,可參考MDN技術文件 PUT : 取代request指定的數據 PATCH : 修改部分request指定的數據 DELETE : 刪除指定資源 HEAD : 只獲取request的header,不要response body OPTIONS : 查看Server提供哪些Request Method CONNECT : 通常用於代理伺服器(Proxy Server) TRACE : 回傳Server收到的request,主要用於測試 request-response 溝通範例向博客來送出請求,回傳博客來2021年度百大暢銷榜數據,request-response內容: 電腦規格(User-Agent參考) 作業系統:Mac OS 瀏覽器:Safari Request URL: https://www.books.com.tw/web/annual10 Request Method: Get Message Body: 無 Request Headers (僅列出部分): Host: www.books.com.tw Referer: https://www.books.com.tw User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15 Response Response Status code: 200 Response body: 博客來2021年度百大暢銷榜網頁數據 Response Headers (僅列出部分): Content-Type: text/html; charset=UTF-8 Expires: Mon, 27 Jun 2022 07:51:02 GMT Cache-Control:max-age=0 備註 Response Header中Cache-Control與Expires說明,可參考循序漸進理解 HTTP Cache 機制","link":"/articles/2022/06/23/%5B%E7%88%AC%E8%9F%B2%E5%9F%BA%E7%A4%8E%E4%BB%8B%E7%B4%B9%5Dpart2/"},{"title":"【爬蟲基礎介紹】part1: 什麼是爬蟲?","text":"什麼是網路爬蟲爬蟲是一個程式 這個程式可以做什麼? 可以模擬人類瀏覽網頁的行為,從中獲取網頁上所需的數據 比較口語化的說法是可以代替你自動從網站中取得資料,幾個優點如下,包括 不需要時時刻刻盯著各大網站的重要訊息,才能獲取第一手資料 從重複copy&paste的過程中解放 獲得好幾個重要小幫手? 爬蟲可以解決什麼問題爬蟲有很多的應用,從文章所述優點舉例說明 不需要時時刻刻盯著各大網站的重要訊息,才能獲取第一手資料 很多租屋族都希望可以抽到社會住宅,但是社會住宅的公告其實是不定期的,常常得知社會住宅釋出時,已經是公告抽籤結果了。此時爬蟲就可以自動幫你監看政府住宅單位的公告,只要政府一公佈消息就即時通知你,讓你能夠短時間內就上網填寫申請表單,不用再時不時上網查詢。 從重複copy&paste的過程中解放 上班族應該都有經驗是有些報告或分析需要定期產出,部分資料需要重複擷取網站數據,再一筆筆複製貼到excel中最後產製結果。如果只有十幾筆很快即能完成,但假使複製的數據來自各網頁且有幾百筆以上的話,就會淪為複製貼上的機器人,手動執行還可能貼錯,而爬蟲就能幫你從這樣呆板的行為中解放,讓你可以多出更多時間優化報告內容。 獲得好幾個重要小幫手 愛看演唱會的粉絲應該深有體驗,演唱會門票開搶之際常常可能5分鐘之內售罄,此時簡直恨不得可以多10幾隻手從好幾台手機或電腦下手開搶。而擁有爬蟲,就能在搶票時多好幾個小幫手協助自己自動搶票,成為搶票達人不再是夢想,當然前提是機器效能夠高。 爬蟲小知識 - 爬蟲名稱由來網路爬蟲(web crawler),也被稱蜘蛛,「web spider」 爬蟲,指的是在程式在網路中爬行,一步一步找到所需的數據 蜘蛛,指的是網際網路就像一張大網,程式就像蜘蛛一樣,會在這張網上到處爬行,最後將資料擷取下來 從網頁取得數據的流程無論是人為或是程式,當我們從網頁獲取資料時,大致的步驟如下:假設我們想知道博客來2021年度百大暢銷榜有哪些書? 博客來2021年度百大暢銷榜 進入博客來網頁:每個我們使用的服務都有一個入口,在這裡先稱為網頁入口,即網頁連結,從瀏覽器中點擊百大暢銷榜的連結 資料的站點:資料的位置不一定放在入口網頁的伺服器上,假設博客來除了入口伺服器外,後台有五台機器,排行榜的資料放在第三台機器上 要資料:當我們點擊連結的那一刻,瀏覽器就向博客來的伺服器索取資料 給資料:當取得資料後,伺服器開始回傳 結果:瀏覽器取得回傳後的資料,並呈現於設備上讓我們瀏覽 補充: 至此從網頁獲取資料的過程就結束了,但在博客來後台每台機器都是可以相通的,也就是說今天資料不管放在第幾台機器上,只要有開放我們都能取得 後台的五台機器們,就是俗稱的內網(區域網路),可以看流程圖上五台機器間之間的連結就像一張網,而外網(公用網路),就是各種開放給外部使用服務的組成,內網加上外網,則形成我們所熟知的網路 如何入門如果你沒有程式的基礎,可以從文章瞭解爬蟲的概念後,透過Octoparse入門實作 Octoparse 為自動化爬蟲生成工具,詳細可參考Octoparse 官網 優點: 圖形化介面 無需有程式背景基礎 可利用拖曳方式自動將資料擷取下來 缺點: 14天免費試用期 執行速度相較一般爬蟲程式慢 可能無法實現擷取網頁細節內容 如果你有程式基礎,或希望學習程式建立屬於自己的爬蟲工具,可依照使用場景與需求,自行選擇適合的程式語言。一般初學者建議從python入手,原因如下: 相較其他程式語言C#或java,簡單易學,較可以快速上手 python的生態圈很廣,因此當學習有問題時,不怕找不到學習資源,且已有很多大神寫好很多套件供使用 python的分布式框架較完善,當有大量的爬蟲需求時建議使用 python為目前主流成熟度高處理數據的程式語言,有相當多處理與分析數據的套件支援,若有後續處理數據的需求會相當推薦 爬蟲禮儀雖然網路資源很多是對外開放,但為了避免爬蟲程式在短時間內快速爬取而造成對方伺服器負擔,在爬蟲的過程中,有些需要注意的細節 避免爬取頻率過高或過量 遵守robots.txt協議的規範,瞭解哪一類的資源可供爬取,規範可參考維基百科 robots.txt","link":"/articles/2022/06/12/%5B%E7%88%AC%E8%9F%B2%E5%9F%BA%E7%A4%8E%E4%BB%8B%E7%B4%B9%5Dpart1/"},{"title":"Airflow with docker compose (airflow+mysql+rabbitmq) 分散式環境","text":"主機環境 兩台主機環境一致 操作系统: Ubuntu 16.04.7 LTS 内核版本: Linux 4.15.0-142-generic docker-compose版本: v1.29.1 叢集環境 管理對應目錄配置對應目錄,當啟用多個service可便於管理 MySQL配置文件: 放在/data/mysql airflow數據目錄: 放在/data/airflow 於serviceA、serviceB皆設定對應container目錄,並設定權限12$ mkdir ./data/airflow/dags ./logs/airflow ./data/airflow/plugins$ echo -e \"AIRFLOW_UID=$(id -u)\" > .env serviceA(docker-compose.yml) 參照檔案建置master,修改yml: airflow單機版建構 github參考: https://github.com/Dawn0472/docker-airflow/tree/main/分散式/serverA MySQL 修改MySQL配置volumes對應路徑 x-airflow-common 環境 新增extra_hosts,設定hostname對應ip位置 修改對應volumes 1234567891011121314151617181920212223242526272829303132333435x-airflow-common: &airflow-common # In order to add custom dependencies or upgrade provider packages you can use your extended image. # Comment the image line, place your Dockerfile in the directory where you placed the docker-compose.yaml # and uncomment the \"build\" line below, Then run `docker-compose build` to build the images. image: ${AIRFLOW_IMAGE_NAME:-apache/airflow:2.2.3} # build: . environment: &airflow-common-env AIRFLOW__CORE__EXECUTOR: CeleryExecutor AIRFLOW__CORE__SQL_ALCHEMY_CONN: mysql+mysqldb://airflow:worker@mysql/airflow # 變更為mysql連線方式 AIRFLOW__CELERY__RESULT_BACKEND: db+mysql://airflow:worker@mysql/airflow # 變更為mysql連線方式 AIRFLOW__CELERY__BROKER_URL: amqp://worker:worker@rabbitmq:5672// # 變更為rabbitmq連線方式 AIRFLOW__CORE__FERNET_KEY: '' AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION: 'true' AIRFLOW__CORE__LOAD_EXAMPLES: 'true' AIRFLOW__API__AUTH_BACKEND: 'airflow.api.auth.backend.basic_auth' _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-} AIRFLOW__CORE__PARALLELISM: 64 AIRFLOW__CORE__DAG_CONCURRENCY: 32 AIRFLOW__SCHEDULER__PARSING_PROCESSES: 4 extra_hosts: - \"host-01:192.168.x.xx\" # worker hostname : ip - \"host-02:192.168.x.xx\" volumes: # 修改對應目錄 - ./data/airflow/dags:/opt/airflow/dags - ./logs/airflow:/opt/airflow/logs - ./data/airflow/plugins:/opt/airflow/plugins user: \"${AIRFLOW_UID:-50000}:0\" depends_on: &airflow-common-depends-on rabbitmq: # 設置rabbitmq service名稱 condition: service_healthy mysql: # 設置mysql service名稱 condition: service_healthy airflow-init 刪除自建目錄command 12mkdir -p /sources/logs /sources/dags /sources/pluginschown -R \"${AIRFLOW_UID}:0\" /sources/{logs,dags,plugins} serviceB(docker-compose_worker.yml) 參照serviceA docker-compose.yml於services中刪除rabbitmq、mysql 需建置webserver,因webserver啟動時會啟動子服務log service,建置webserver才能於網頁中看到worker的log github參考: https://github.com/Dawn0472/docker-airflow/tree/main/分散式/serverB worker 刪除depends_on內容 啟用log server port 12345678910111213141516171819202122airflow-worker: <<: *airflow-common hostname: host-02 # 設定host_name command: celery worker ports: - \"8793:8793\" # 啟用log server port healthcheck: test: - \"CMD-SHELL\" - 'celery --app airflow.executors.celery_executor.app inspect ping -d \"celery@$${HOSTNAME}\"' interval: 10s timeout: 10s retries: 5 environment: <<: *airflow-common-env # Required to handle warm shutdown of the celery workers properly # See https://airflow.apache.org/docs/docker-stack/entrypoint.html#signal-propagation DUMB_INIT_SETSID: \"0\" restart: always depends_on: airflow-init: condition: service_completed_successfully x-airflow-common 環境 修改連接service 刪除depends_on內容 1234567891011121314151617181920212223242526272829x-airflow-common: &airflow-common # In order to add custom dependencies or upgrade provider packages you can use your extended image. # Comment the image line, place your Dockerfile in the directory where you placed the docker-compose.yaml # and uncomment the \"build\" line below, Then run `docker-compose build` to build the images. image: ${AIRFLOW_IMAGE_NAME:-apache/airflow:2.2.3} # build: . environment: &airflow-common-env AIRFLOW__CORE__EXECUTOR: CeleryExecutor AIRFLOW__CORE__SQL_ALCHEMY_CONN: mysql+mysqldb://airflow:[email protected]:3305/airflow # 連接serverA mysql AIRFLOW__CELERY__RESULT_BACKEND: db+mysql://airflow:[email protected]:3305/airflow # 連接serverA mysql AIRFLOW__CELERY__BROKER_URL: amqp://worker:[email protected]:5672// # 連接serverA rabbitmq AIRFLOW__CORE__FERNET_KEY: '' AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION: 'true' AIRFLOW__CORE__LOAD_EXAMPLES: 'true' AIRFLOW__API__AUTH_BACKEND: 'airflow.api.auth.backend.basic_auth' _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-} AIRFLOW__CORE__PARALLELISM: 64 AIRFLOW__CORE__DAG_CONCURRENCY: 32 AIRFLOW__SCHEDULER__PARSING_PROCESSES: 4 extra_hosts: - \"host-01:192.168.x.xx\" # worker hostname : ip - \"host-02:192.168.x.xx\" volumes: # 修改對應目錄 - ./data/airflow/dags:/opt/airflow/dags - ./logs/airflow:/opt/airflow/logs - ./data/airflow/plugins:/opt/airflow/plugins user: \"${AIRFLOW_UID:-50000}:0\" 啟動docker-compose 12$ docker-compose up airflow-init # 初始化服務,確保container連結正常$ docker-compose up -d # 於背景執行中創建airflow container airflow啟動畫面 flower啟動畫面 RabbitMQ啟動畫面 數據同步 讓server間數據同步,當scheduler進行排程調度時才不會發生找不到文件而導致無法運行排程的錯誤發生 數據同步有兩種方式 只更新一台server,讓所有server數據同步 只更新一台server,讓其他server對應更新數據的server位置 本次利用lsyncd實現多台server同步部屬,免密碼ssh登入 serverA lsyncd下載安裝 1$ sudo dpkg -i lsyncd_2.2.3-1_amd64.deb 檢查lsyncd版本 啟動lsyncd 12$ systemctl start lsyncd$ systemctl status lsyncd 建置lsyncd設定檔,path=/etc/lsyncd/lsyncd.conf.lua 1$ sudo vim /etc/lsyncd/lsyncd.conf.lua # 設定連接內容 配置節點之間通過公鑰連接 airflow-sync:私鑰 airflow-sync.pub:公鑰 1$ ssh-keygen -t rsa -C \"airflow-sync\" -b 4096 #生成名稱為airflow-sync的密鑰 將pub 公鑰內容複製到遠端serviceB上,遠端serviceB使用者目錄中.ssh/authorized_keys中會有對應公鑰內容 1$ ssh-copy-id -i ~/.ssh/airflow-sync.pub [email protected] 放置測試文件於serviceA 路徑:/data/airflow/dags/sample-dag.py 列出hostname,以便測試是否task在不同機器上運行 dags 引用自How to Scale-out Apache Airflow 2.0 with Redis and Celery 12345678910111213141516171819202122232425262728from airflow import DAGfrom airflow.operators.bash import BashOperatorfrom datetime import datetime, timedeltadefault_args = { 'owner': 'Dawn', 'retries': 2, 'retry_delay': timedelta(minutes=1) }with DAG('dist_example', start_date=datetime(2022, 5, 13, 16, 34), schedule_interval=\"*/10 * * * *\", ) as dag: create_command = 'echo $(hostname)' t1 = BashOperator( task_id='task_for_q1', bash_command=create_command, dag=dag ) t2 = BashOperator( task_id= 'task_for_q2', bash_command=create_command, dag=dag ) t1 >> t2 於airflow運行 host-01 host-02 參考來源 Airflow2.2.3 + Celery + MySQL 8构建一个健壮的分布式调度集群 lsyncd 官網","link":"/articles/2022/06/08/Airflow-with-docker-compose-airflow-mysql-rabbitmq-%E5%88%86%E6%95%A3%E5%BC%8F%E7%92%B0%E5%A2%83/"},{"title":"從Anaconda到pyenv:在ubuntu上使用pyenv建立Python開發環境","text":"緣由初始學習Python便是以資料工程的領域入門,Anaconda提供不少資料科學與分析所需的套件,且預設安裝Jupyter notebook,基於傻瓜部署,一路使用至今。因如下介紹的conda的部署缺點,一直有考慮其他Python開發環境部署方式。 眾所皆知,Apple在2021推出自製ARM M1晶片,本篇操作載入ARM架構下的image,Ubuntu 20.04.5 LTS。 以pyenv + virtualenv紀錄部署上的重點。 Python開發環境部署 Anaconda 優點:傻瓜部署,只需按照官方說明安裝,安裝完後依照專案設定python版本與env,即可快速使用 缺點: 因預設載好各種資料科學套件包,從下載到安裝完成需30分鐘以上 可使用conda與pip安裝套件,當環境需要轉移,整理requirement.txt耗時 當有封裝程式需求時,因有非常多套件一起封裝,最終封裝完的程式檔案可能佔用太多空間 Miniconda因肥大的資料科學套件引人詬病,miniconda是anaconda的精簡版,只有環境控制的相關功能,沒有多餘的library 優點:免預先安裝多餘library,可繼續使用conda管理python env 缺點:與Anaconda相同,當環境需要轉移,整理requirement.txt耗時 pyenv 優點: 與Miniconda類似,極輕量 僅用pip進行管理 缺點:僅有python版本管理,env管理需搭配pyenv-virtualenv 主機環境 操作系统: Ubuntu 20.04.5 LTS (Focal Fossa) 内核版本: 5.15.0-48-generic 安裝pyenv安裝參考pyenv 官方 GitHub 從GitHub載入pyenv 1git clone https://github.com/pyenv/pyenv.git ~/.pyenv 在 ~/.bashrc 添加以下字段 123echo 'export PYENV_ROOT=\"$HOME/.pyenv\"' >> ~/.bashrcecho 'command -v pyenv >/dev/null || export PATH=\"$PYENV_ROOT/bin:$PATH\"' >> ~/.bashrcecho 'eval \"$(pyenv init -)\"' >> ~/.bashrc 在 ~/.profile 添加以下字段 123echo 'export PYENV_ROOT=\"$HOME/.pyenv\"' >> ~/.profileecho 'command -v pyenv >/dev/null || export PATH=\"$PYENV_ROOT/bin:$PATH\"' >> ~/.profileecho 'eval \"$(pyenv init -)\"' >> ~/.profile 重啟shell,使環境變數生效 1exec \"$SHELL\" 查閱pyenv下所有Python版本,檢查是否安裝成功 1pyenv versions 輸出如下說明即代表安裝成功 1* system (set by /home/username/.pyenv/version) 使用 pyenv install 安裝 Python 列出所有可安裝的Python版本 1pyenv install --list 安裝Python 3.6.5 1pyenv install 3.6.5 執行後出現訊息1234Downloading Python-3.6.5.tar.xz...-> https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tar.xzInstalling Python-3.6.5...Installed Python-3.6.5 to /home/dawn/.pyenv/versions/3.6.5 等待安裝完成後,重新查看pyenv版本輸出如下,可切換環境使用。PS: 僅一種版本對應一個環境,並不夠便捷,因此安裝pyenv-virtualenv可以更方便協助管理環境。12* system (set by /home/dawn/.pyenv/version) 3.6.5 安裝pyenv-virtualenv依據官網說明,pyenv-virtualenv為Pyenv的外掛套件,可以管理Python的虛擬環境 從GitHub載入pyenv-virtualenv 1git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv 在 ~/.bashrc 添加以下字段 1echo 'eval \"$(pyenv virtualenv-init -)\"' >> ~/.bashrc 重啟shell,使環境變數生效 1exec \"$SHELL\" 創建虛擬環境,環境名稱myenvPS:需要注意要先以pyenv建立3.6.5的python版本,才有辦法創建該版本的env,若無指定版本,則以系統預設版本為主 1pyenv virtualenv 3.6.5 myenv 切換環境 global12pyenv global myenv # 設定系統預設的python環境為myenvpyenv global 3.6.5 # 設定系統預設python版本 查閱系統當下版本,以系統設定python版本為例,輸出如下1234 system* 3.6.5 (set by /home/dawn/.pyenv/version) # *為系統預設版本 3.6.5/envs/myenv myenv local可在所屬專案目錄下,指定專案Python版本,該目錄會出現.python-version 檔案,隨後即可以pip安裝package1pyenv local myenv 啟動、退出、移除環境 啟動環境 1pyenv activate myenv 退出環境 1pyenv deactivate 移除環境 1pyenv uninstall myenv 感想從參考文章告別 Anaconda:在 macOS 上使用 pyenv 建立 Python 開發環境 看到註解 「不同 Python 版本間的虛擬環境管理」和「不同專案間的虛擬環境管理」基本上是兩件事,只不過 Anaconda 透過 conda 同時都能做到而已。 實際以pyenv + virtualenv操作後更能瞭解該說明,是以往僅使用conda來管理環境時沒有思考過的事。","link":"/articles/2022/09/28/%E5%BE%9EAnaconda%E5%88%B0pyenv%EF%BC%9A%E5%9C%A8ubuntu%E4%B8%8A%E4%BD%BF%E7%94%A8pyenv%E5%BB%BA%E7%AB%8BPython%E9%96%8B%E7%99%BC%E7%92%B0%E5%A2%83/"}],"tags":[{"name":"爬蟲","slug":"爬蟲","link":"/tags/%E7%88%AC%E8%9F%B2/"},{"name":"python","slug":"python","link":"/tags/python/"},{"name":"docker","slug":"docker","link":"/tags/docker/"},{"name":"airflow","slug":"airflow","link":"/tags/airflow/"},{"name":"pyenv","slug":"pyenv","link":"/tags/pyenv/"},{"name":"Anaconda","slug":"Anaconda","link":"/tags/Anaconda/"}],"categories":[{"name":"爬蟲","slug":"爬蟲","link":"/categories/%E7%88%AC%E8%9F%B2/"},{"name":"維運","slug":"維運","link":"/categories/%E7%B6%AD%E9%81%8B/"}]}