如何在Ubuntu 18.04上安裝與設定HP印表機工具

前言

因為辦公室是使用HP印表機進行影印,以往我在辦公室有文件需要列印的時候,我都是使用辦公室所配發的Win 10筆電進行列印,這樣其實是不方便的。

因為每次都要在辦公桌上切換不同的電腦進行列印的操作,熟悉我的人都知道,我基本上都是使用Ubuntu/Linux筆電進工作,所以我最近找了一些文章並把HP印表機工具,在Ubuntu 18.04上的設定記錄下來。

讓大家知道,HP印表機在筆電上要怎麼運作的。

前置環境

在開始本篇的教學前,需要注意下面的幾點事項:

  • 準備好Ubuntu 18.04的筆電或是電腦

安裝相關所需要的套件

在使用HP印表機工具前,需要透過下面的指令來更新與安裝我們所需要的套件


sudo apt-get update

sudo apt-get install hplip hplip-gui hplip-data hplip-doc hpijs-ppds libsane-hpaio printer-driver-hpcups printer-driver-hpijs

安裝好之後,我們可以透過指令的方式啟動HP-setup,這是印表機設定工具


python3 $(which hp-setup)

這邊要注意的是,需要使用Python3開啟,因為大多數環境預設,python指令為Python2。

所以要在最前面指定python3當作執行的程式。

執行下去之後,會看到下面的畫面:

這是一個HP裝置管理器,透過它可以幫我們快速找到印表機裝置的位置,裡面有幾種選項可以選擇,分別是:

  • USB找尋印表機裝置
  • 透過網路(包含無線,有線等網路)直接連線印表機裝置
  • 無線網路,需要暫時連接USB網路
  • 序列port方式連接

以我在辦公室來說,通常大部分都是選擇第二個選項,我們可以透過區域網路方式,找尋到確的印表機位置。

可是當你選擇下去並按下「Next」之後,會出現如下的錯誤:

這是因為,HPLIP沒有辦法自動找到網路上的印表機,這時候,需要打開「Show Advanced options」並勾選「Manual Discovery」手動將印表機所在的IP填上去:

 

填完之後再去按下「Next」,這時候就會順利找到了。如下圖,就會有那台印表機的資訊

接著再按下「Next」就會把印表機安裝好了。到這裡,就是把印表機設定好完成的步驟,那接下來後面就是可以開始列印文件了。

首先,我們先開啟一份PDF檔案,我使用「Document Viewer」做開啟的動作。

接著,按下「Print」選項,如下圖:

按下去之後,會有印表機裝置清單:

接著切換到「Advanced」選項,如下截圖:

我們從截圖中可以看到有一個選項叫做「Page Source」,可以選擇紙夾的部份,裡面有紙夾1,紙夾2與自動偵測可以選擇。那因為我本來是用自動偵測的選項,可是不知道為什麼,每次檢查完紙夾1之後就不能往下檢查了,會卡在紙夾1中沒有紙張。

我為了要解決上述的問題,我就直接指定紙夾2當作列印紙張的來源,後來就可以順利的列印出文件了,沒有任何的問題。

參考資料

  • https://askubuntu.com/questions/1058742/how-to-install-hp-printer-in-ubuntu-18-04

如何利用在Azure上的Azure Web App部署一個Docker容器

前言

相信在看這篇文章之前,已經先看過這篇文章了。從前一篇文章,我們可以得知該如何利用Azure Web App上部署的方法把我們的專案部署上去。

可是,這個沒辦法滿足下列的要求

  • 以PHP環境來說,預設在Azure Web App上的環境是PHP + Apache,那如果我們要PHP + Nginx呢?
  • Azure Web App部署上去會觸發Azure所客製的部署引擎Kudu,若不熟悉腳本語言,還需要再花額外的時間去學習

為了要解決上述的問題,Azure Web App提供另一項的部署方式,那就是用Docker container方式,透過編寫的Dockerfile或docker-compose.yml方式,Azure Web App會在部署的時候讀取它們並部署成一個container,即是一個容器為一個Web App Service的概念。

本文章,就是要使用Azure Web App並透過載入Docker 映像來達到部署Web App Service。

登入Azure portal

首先,先登入Azure portal,Web方式管理Azure雲端運算平台的服務。

接著,在利用Docker container部署一個Azure Web App之前,需要將我們需要用到的Docker 映像發怖到網路上的平台,因為Azure Web App用Docker容器部署的時候,可以接受以下幾種方式:

  • 從外部Docker Hub載入
  • 從Azure Container Registry載入
  • 快速入門
  • 私人存放Docker映像檔server

本章節中,我們只使用「Azure Container Registry」這種方式載入我們所需要的Docker映像檔。原因是因為:

  • 我們需要建立一個Docker私人映像檔
  • 客製化Docker映像,因此快速入門所預設好的映像不適合這次的文章要求
  • 我們沒有私人存放Docker映像檔的server,因此此方法也不適合
  • Azure Container登錄,就是在Azure雲端運算平台上面建立一個私人的Docker Hub,透過它可以在Azure Web App部署的時候指定來源的Docker映像,進而達到部署的效果

我們在上圖中的「搜尋資源,服務及文件的地方」輸入「容器登錄」就可以得到如下的截圖:

因為我在之前有建立一個Docker容器登錄的位址,因此截圖上有出現在清單中,接著按下「新增」,就會看到下面的截圖:

就先取好自己的Docker container Registry名字,還有其他選項,如下圖所示:

都確認之後,接著按下「建立」的按鈕,就會開始建立Azure Container Registry位置了。

建立完成之後,在清單中就會看到剛剛建立的Azure Container Registry了。

點擊剛剛所建立好的容器登錄。

就會看到這樣的截圖如下:

點擊「存取金鑰」並把管理使用者「啟用」,這樣就可以允許Azure Web App在部署的時候去存取此Azure Container Registry上的Docker映像了。

接著,打開終端機,假設已經把「az」安裝好了(若沒有安裝,請先讀這篇文章),我們可以輸入如下的指令進行登入:


az acr login --name=your-acr-name

登入成功後,會出現下列的訊息


Login Succeeded

接下來,就可以把本地建置好的Docker映像發怖到我們先前所建立好的Azure Container Registry了

我們先標記目前的Docker映像的版本,這樣在Azure Container Registry上選擇版本的時候更加容易,可以利用下面的指令來達成


docker tag database-adminer your-acr-name.azurecr.io/database-adminer:v1

database-adminer是我在本地端Docker映像檔的名稱,而「your-acr-name」是之前步驟建立Azure Container Registry的名稱。

建立好標籤之後,接著再用下面的指令將本地端的Docker映像傳輸到先前所建立的Azure Container Registry。


docker push multidbp.azurecr.io/database-adminer:v1

都建立完成之後,回到Azure Container Registry頁面並點選「存放庫」可以發現剛剛所建立的Docker映像已經在上面了,如下截圖:

接著點選進去,就可以看到目前推送上去所有的的標籤清單了

我們完成了Docker映像的推送後,接下來可以用Azure Web App部署了

首先,我們先進到如下圖的「Azure Web應用程式」頁面並再新增一個新的Web應用程式,選擇相關的選項如下圖:

在圖中我們可以得知,我們取一個Web App名字叫做「database-adminer-docker」並把部署方式選擇「Docker映像」,其他選項都用與之前文章相同即可。接著點選「下一步:Docker」,就會到下面的截圖:

我們選擇「單一容器」,映像來源選擇「Azure Container Registry」,接著選擇登錄容器的名稱,映像以及標籤版本,啟動命令留下空白,這裡是因人而異,原因是因為我們在「Dockerfile」裡面已經有明確的指定要執行的指令,因此不需要再額外輸入需要執行指令。

接著就「下一步 標籤」再接著按「下一步 檢閱及建立」,最後就按下「建立」,如下截圖。

接著就跑起來了,如下截圖:

參考資料

  • https://docs.microsoft.com/zh-tw/azure/app-service/containers/tutorial-custom-docker-image
  • https://blog.miniasp.com/post/2015/05/04/Intro-Azure-Web-App-Kudu-engine
  • 文章所使用到的專案:https://github.com/peter279k/database-adminer

如何在Azure上使用Azure Web App部署一個Web應用程式

前言

在開始本文章前,先講個故事。

回到2018年,剛進去公司的時候,我有一個快要離職的同事,它知道我要開一個新計畫需要建置一個資料視覺化的系統並要在移入廠商內網之前,要在外面一個地方做一個展示。

他就說:「那可以在Azure上面開一個虛擬機器」

所以那因為這樣,我就在Azure雲端運算平台上面開一台虛擬機器了。開了之後,發現辦公室裡面大家也是這樣開虛擬機器,我都懷疑這樣不是就沒有用到Azure的雲端服務的優勢了嘛?

後來,我又想到之前學的,雲端服務三層架構(不知道的可以去看此篇文章),我覺得,Azure應該也有PaaS的服務才對,那後來再跟其他人交流,講到在Azure上面的費用,聽到我們需要在平台上面一個月花上2萬多塊也感到不可思議,也認為這樣在雲端運算平台上面花太多錢了,他們聽完我講我們都在上面開很多虛擬機器跑服務,也都驚訝不已。

本文章,是要講述如何使用Azure上面所提供PaaS功能的「Azure Web 應用程式」來部署一個單一個PHP Web應用程式。

Azure Web App概覽

首先,我們可以先從下面截圖來一窺Azure Web App部署架構圖。

從上面的架構圖我們可以知道,在「Azure Web App」部署上有幾種方法可以成功部署成「Azure Web App」,相關部署方法如下:

  • FTP deployment, FTP部署,這個是屬於最基本的,就是透過FTP帳號與密碼把專案推送上去
  • GitHub deployment, GitHub部署,這個是利用GitHub OAuth的功能授權給Azure,讓Azure可以存取指定的專案達到部署的效果
  • Local Git, 本地端Git部署,這是利用本地端自己的Git專案,將其部署到Azure Web App上
  • BitBucket deployment, BitBucket部署,這個與GitHub相同,都是透過授權給Azure可以存取指定的專案(repositories),來達到部署
  • Azure repos, 這個是指可以利用「Azure DevOps」與持續整合與部署做結合

本文章,只會介紹前面四種的部署方式,至於「Azure repos」,因為步驟與建置較為複雜,因此後續的文章才會有此篇文章專門做此介紹

前置條件

在開始本篇文章操作之前,下面的東西是不可或缺且需要會的

  • Git
  • FTP使用
  • az command, Azure CLI, 若沒安裝,請先看此教學
  • 有GitHub帳號(若需要透過此帳號上面的專案進行部署)
  • 有BitBucket帳號(若需要透過此帳號上面的專案進行部署)

建立Azure Web應用程式

首先,我們先登入Azure portal,網址:https://portal.azure.com

接著,在下方截圖的搜尋欄位輸入「Azure Web App」,接著就會看到下方截圖的「應用程式服務」

接著就會看到所有的Web應用程式的清單,如下截圖。

接著,按下左上角的「新增」按鈕,我們就會跳到新增Web應用程式的頁面了,如下圖。

我們填完所屬的資源群組名稱後,接著,這個頁面往下拉一點,可以看到下面的截圖:

從上面的截圖可以知道,我們有下列的選項可以選擇:

  • 名稱,這裡是可以取名稱,使用「azurewebsites.net」的子網域名稱
    • 子網域部份,由於是大家一起共用這個主網域的,因此不可以跟其他人重複,這裡我取的範例是「database-adminer」
  • 發佈,這裡可以選擇「代碼」或是「Docker映像」。代碼指的是自己的專案,選擇「代碼之後」,並不需要再做額外的其他設定,選擇「Docker映像」還需要在設定
    •  Docker映像得來源位址
    • 這裡選擇是「代碼」,使用「Docker映像」部份則留到日後的文章再說
    • 選擇「代碼」之後,需要選擇「執行階段堆疊」,這裡要選擇需要在上面跑的程式語言,因為本文章範例是建立PHP Web應用程式,所以我們可以選擇如下截圖的PHP版本,我們這裡選擇PHP-7.3

  • 地區,就是希望在哪個地方運行這個Web應用程式,價錢會會隨著地方的不同而有所不同,有些地方價錢較高但是離需要服務的國家近等,自行選擇作取捨
  • APP SERVICE 方案,就是自行選擇所需要的方案,這裡我選擇「基本B1」方案,方案日後仍可以再自己再調整

按照上述的建議,設定好之後,按下「檢閱及建立」,檢查完成後,接著再按下「建立」,就會將此Web應用程式的實例建立起來了。

建立好之後,回到首頁,點選下面截圖的「應用程式服務」

接著,我們可以到所有應用程式服務的清單,並找到剛剛建立的「database-adminer」的應用程式服務。

點選「database-adminer」按鈕進去之後,就可以看到此應用程式的設定頁面了

從上面截圖的設定頁面,我們可以得知幾個事項:

  • URL網址
  • 目前的APP SERVICE方案
  • FTP位址
  • 左邊的列表我們可以看到,有「部署」的區塊,此區塊中的「部署中心」是下一章節會用到的

Azure Web應用程式部署設定

本章節,我們要點選上一張Web應用程式設定頁面截圖中,左邊的「部署中心」選項,點選之後,我們可以看到下面的截圖。

 

往下拉之後,會再看到下面有另外三個部署方法,如下截圖:

Azure Web應用程式GitHub部署設定

假設我們需要使用GitHub上的專案來部署到指定的Azure Web應用程式上面

首先,先附上利用GitHub的部署Azure Web應用程式架構圖。

  • 開發者會先授權給Azure Web App讓它可以讀取開發者GitHub帳號上的專案
  • 透過指定專案的方式,會建立Webhook,每當有新的commit更新上去的時候,就會自動推上去做更新

我們選擇GitHub並授權給Azure Web App存取上面的專案

點選之後,再按下「授權」按鈕會跳出授權的畫面,如下截圖

GitHub授權頁面往下拉,並按下「Authorize AzureAppService」按鈕,接著就授權完成了。有可能,GitHub會再度要求輸入一次使用者密碼以便確認授權。

完成之後,授權畫面就會關閉,並再回到部署設定頁面,這個時候就會發現GitHub帳號名稱就會在上面,這就表示已經授權成功了。

接著按下「繼續」按鈕,則會看到下面的選項:

  • 第一個服務是使用一個東西叫做「Kudu」服務透過服務定義的部署腳本進行自動部署程式碼或專案
  • Azure Pipelines,是使用「Azure DevOps」,並透過持續整合服務,將服務做持續部署的動作,因為這個服務牽涉到要開啟權限與DevOps的概念,因此本篇文章暫不討論

接著按下「繼續按鈕之後」,會來到選擇存放專案的地方,選擇適當的組織,存放庫名稱與分支。

接著選擇如下方的專案

接著按下「繼續」,再按下如下面截圖的「完成」就部署完成了

部署中心設定頁面就會變成下面截圖這樣了

我們再去打開「https://database-adminer.azurewebsites.net」網址,就會看到如下的畫面了

Azure Web應用程式BitBucket部署設定

與GitHub的步驟類似,可以選擇下面截圖之後,後面的步驟與「GitHub」部署專案章節步驟雷同

Azure Web應用程式Local Git部署設定

顧名思義,就是把本地的Git存放庫直接推到Azure Web App並透過Azure Web App進行內部的部署動作。

設定完成之後,Azure Web App會設定一個遠端的Git存放庫,讓本地端的Git存放庫可以推上去並進行部署

接著我們回到本地端的,打開終端機打上下面的指令將上述的遠端Git存放庫網址加入到本地端的遠端存放庫清單裡面


git remote add azure https://database-adminer.scm.azurewebsites.net:443/database-adminer.git

接著,我們利用下面的指令把專案推上去

接著,要為遠端Azure的存放庫設定一組帳號密碼,如此一來才可以將本地端的Git存放庫推上去並達到部署的效果

假設本地端已經有「az」指令,在終端機輸入:


az webapp deployment user set --user-name your-user-name --password your-password

最後會輸出像下面的response JSON

{
"id": null,
"kind": null,
"name": "web",
"publishingPassword": null,
"publishingPasswordHash": null,
"publishingPasswordHashSalt": null,
"publishingUserName": "multidbp",
"scmUri": null,
"type": "Microsoft.Web/publishingUsers/web"
}

設定好帳號與密碼之後,就可以透過下面的指令把專案推上去了


git push azure master

會問帳號與密碼,這時候就輸入剛剛所設定的帳號與密碼就可以通過遠端Azure存放庫的認證把本地Git專案部署上去了

推上去的過程會類似如下圖這樣:


Username for 'https://database-adminer.scm.azurewebsites.net:443': your-user-name
Password for 'https://multidbp@database-adminer.scm.azurewebsites.net:443':
Counting objects: 37, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (32/32), done.
Writing objects: 100% (37/37), 292.51 KiB | 6.80 MiB/s, done.
Total 37 (delta 13), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id 'aee14e6771'.
remote: Running custom deployment command...
remote: Not setting execute permissions for bash deploy.sh
remote: Running deployment command...
remote: PHP deployment
remote: Kudu sync from: '/home/site/repository' to: '/home/site/wwwroot'
remote: Ignoring: .deployment
remote: Copying file: '.env.example'
remote: Copying file: '.htaccess'
remote: Copying file: '.htpasswd'
remote: Copying file: 'Dockerfile'
remote: Ignoring: deploy.sh
remote: Copying file: 'index.php'
remote: Copying file: 'nginx-default.conf'
remote: Deleting file: 'README.md'
remote: Ignoring: .git
remote: No COMPOSER_ARGS variable declared in App Settings, using the default settings
remote: Composer settings: --no-interaction --prefer-dist --optimize-autoloader --no-progress --no-dev --verbose
remote: /home/site/wwwroot
remote: /home/site/wwwroot
remote: Found entry .env.example
remote: ~/site/wwwroot ~/site/repository
remote: ~/site/repository
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Deployment successful.
remote: App container will begin restart within 10 seconds.
To https://database-adminer.scm.azurewebsites.net:443/database-adminer.git
* [new branch] master -> master

在推送的過程中,會將Git專案中的檔案一併做複製並做一些設定的動作

Azure Web應用程式FTP部署設定

這章節,是最簡易的部署,簡單來說,就是透過Azure給的FTP帳號與密碼,透過FTP傳輸檔案的方式把本地端的專案部署上去。

FTP本身已經是內建的功能了,如下截圖:

結論

  • 本文章都是用PHP作為範例來部署Web應用程式
  • 以PHP Web應用程式來說,進入點是「index.php」
  • 每當要換部署方式時,記得選擇「中斷連接」來取消當前的部署方式

  • 其他程式語言其實也是大同小異,需要再舉一反三即可

參考資料

  • https://docs.microsoft.com/zh-tw/azure/app-service/containers/tutorial-custom-docker-image
  • https://docs.microsoft.com/zh-tw/azure/app-service/containers/quickstart-docker-go
  • https://mikepfeiffer.io/azure-docker-containers.html
  • https://www.dragonbe.com/2018/02/deploy-docker-containers-fast-to.html
  • https://docs.microsoft.com/zh-tw/azure/app-service/deploy-local-git
  • 使用到的專案:https://github.com/peter279k/database-adminer

如何在Azure上部署一個Azure MySQL Database

前言

最近在公司裡,有在使用Azure雲端服務來架設各式各樣的服務,供測試與部署。

那隨著Azure金錢消耗量很大,負責管理Azure的人慢慢意識到Azure怎麼會這麼燒錢?

後來我慢慢的發現,最後得到下面這張結論圖:

原來是一開始大家就對於Azure的使用上弄錯了方向。其主要原因如下:

  • 不懂雲端運算平台的架構,導致大家都在IaaS層建立資源機器
  • 當然我前二個計畫也是在IaaS上開機器做服務出來,當然我開始了一些改變
    • 去年的時候,第一台機器所對應的計畫,就跟其他人一樣,都是開一台運算資源機器出來,上面架設需要的環境與安裝服務。
    • 第二台機器,一樣也是開資源機器起來,但是跟前一個不同的是,我把所有的服務做容器化,讓服務更好掌控與管理,不過還是一樣,還是需要在機器上建置Docker所需要的必要環境
    • 未來計畫,以Azure來說,會朝向使用PaaS,如「Azure Web App」等
      • 將每個需要的服務分開,並使用Azure MySQL/PgSQL/SQL 等DB的PaaS建立資料庫instance實例,以達到共用資料庫的目的

本文章,主要是要探討的內容如下:

  • 使用Azure上屬於PaaS種類包含
    • 「Azure Web App」與「Azure DB」
    • 以「Azure MySQL DB」服務建立MySQL資料庫

Azure Database介紹

在Azure雲端運算平台上,有現成的資料庫的服務可以使用與建立,那這些也算是PaaS期中的應用之一,其最主要的目的就是可以讓開發者省略設定與安裝資料庫的動作,透過Azure針對資料庫配置好的設定來建立資料庫,這樣的好處如下:

  • 開發者可以專心開發並不需要花費額外的心力在建置與設定資料庫上
  • 對於小型團隊,計畫有很大的幫助

Azure MySQL Database建立步驟

首先,我們可以先登入Azure portal,網址:https://portal.azure.com

登入之後,我們可以看到下面的截圖所示:

接著,點擊右邊的「新增資源」並會看到右邊有可以建置的資料庫種類清單,詳細如下面截圖

我們從上面的截圖可以找到我們要的「MySQL」資料庫,因此我們選擇「適用於 MySQL 的 Azure 資料庫」這個來建立本篇文章所要展示的資料庫

點擊下去之後,會有一些相關的設定需要填寫,如下截圖

因為我已經有建立一個名稱叫做「electric-data」的資料庫了,所以上面的截圖在資料庫名稱有紅色驚嘆號是很正常的。

其他的欄位如資料庫名稱,使用者帳號,密碼以及主機座落的位置以及MySQL版本等都可以自行填寫,這邊只是一個範例。

接著,都填寫完成之後,按下「建立」按鈕就可以開始把需要的資料庫建置起來了。

回到首頁,我們在搜尋欄位地方輸入「MySQL」就可以找到「適用於 MySQL 伺服器的 Azure 資料庫」這個名字,點選下去之後,就會看到所有MySQL資料庫的清單列表。

從上面截圖可以得知,我們有一個叫做「electric-data-store」的資料庫可以選擇,那點擊下去之後,就會有此MySQL資料庫相關設定頁面可以選擇。

下面截圖可以得知,裡面會有Azure MySQL資料庫相關的所有設定

從上面截圖,我們可以知道相關設定如下

  • 資料庫系統管理員帳號與密碼設定
  • 資料庫SSL連線啟動與設定
  • 連線設定「Connection security」

資料庫連線設定

點選左邊列表的「Connection security」,我們可以發現有防火牆規則與SSL連線設定可以設置,那這邊就是加入可以允許連線的IP位址範圍。

結論

本文章中,利用Azure portal管理介面去示範新增一個「Azure MySQL Database」並可以透過上面的資料庫設定頁面可以設定相關與MySQL資料庫有關的設定。

當然,Azure雲端運算平台上面還有其他得資料庫可以新增與使用,這就要留到後面有用到再說吧,不過我覺得其他新增資料庫的方式應該也是大同小異,與新建「MySQL」資料庫的方式不會差太多才對。

淺談雲端服務與市面上的各式雲端運算平台服務

前言

其實這個概念已經是老掉牙了,這個技術大概是在2008年開始有相關研究一直到現在,還是有很多人不知道這個最基礎的概念與雲端運算架構。

為什麼要知道這個概念?不知道不是也可以使用部署相關的服務也可以用的好好的嘛?

這個原因,其實主要如下:

  • 若是知道概念的話,才會知道在雲端運算平台上,每一種價格會是不一樣,需要依照目前自己需要的服務做選擇,而不是每次都在開VM,虛擬機器解決一切的問題,那個花費是很高昂的。
  • 另外一個原因,是因為,我目前服務公司所使用的Azure平台很花錢。
    • 從大家行為模式來看,其實可以發現,大家不會善用Azure平台上的服務
    • 而最終大家都去選擇最花錢的服務:開啟運算VM (IaaS)。

本文章,是要淺談何謂「雲端運算」,雲端運算中分成哪幾層,以及對應到目前市面上的雲端服務有哪幾層。

什麼是雲端運算?

簡單來說就是,把服務,運算等功能都部署到網路上,而網路上主機通常都是有好幾個機房所組織而成的,那整個各地機房組起來就稱為「雲」,那上去的服務你不知道放在哪個地方,只知道你的服務座落在某一個城市或是地點而已,確切的地方不知道。

服務與運算上雲端,有幾個好處:

  • 不需要自行管理伺服器server等相關工作,把那些時間節省並專心在開發服務上
  • 雲端平台上把所有服務與資源都切開,也就是把服務最小化,因此我們要部署一個服務,或是網頁應用程式,並不需要像以前一樣租一台server並從頭到尾建設自己要的環境。
  • 切成一個個服務就對應到一個容器(Container),這樣一來在管理與部署上會顯的更方便
  • 在價錢方面來說,開啟一個運算資源的虛擬機器,毋庸置疑在雲端運算平台上是一個奢侈的行為,而這樣的行為是最貴的,以一個容器化的概念去對應到一個實例(instance),這樣價錢是最便宜且實用

我認為的缺點如下:

  • 每個雲端運算平台服務所提供的功能不盡相同,需要多花額外的時間學習與設定,導致學習曲線較長。
  • 要達到善用雲端運算平台服務,需要有一些前置條件
    • 了解何謂容器化(Docker container)與虛擬機器(VM)的差別
    • 了解部署的整個流程
    • 了解與熟悉Linux作業系統上的指令操作

一般主機租用與雲端運算平台差異

在雲端運算平台這個概念還沒有出來以前,可能聽過,像是VPS,shared hosting以及dedicated hosting等服務。那這個跟雲端運算平台有什麼差別?其實差別蠻大的。

首先,先以傳統主機的介紹如下:

  • shared hosting,共享主機,他的架構很簡單,就是在一台機器上面,切出一個空間,讓你放置需要執行的程式,那這個空間對於整體主機來說所有的資源都是共享的,所以當資源很大的鄰居的時候,就會有很明顯的影響,比如說網頁速度載入會變慢等。慢慢的這種主機效率不佳之後,就逐漸式微了。
  • VPS,Virtual Private Server,全名叫做「虛擬私人主機」,這個指的是,會利用虛擬化的技術將一台實體主機區分成好幾個虛擬機器,這些虛擬機器並不會互相共用自己的資源,所以會比一般的共享主機要來的好。那主要的虛擬化技術有
    • KVM,這個會模擬Kernel出來,所以內部虛擬機器可以自行升級Kernel,也可以在此虛擬機器底下建置多個所需要的Docker container
    • OpenVZ,這個會與實體主機上的Kernel共用,所以無法自行更改Kernel,而也無法模擬出Docker container在此虛擬化出來的機器上
  • Dedicated hosting,實體主機,這其實就是一台或多台主機,完全可以按照自己的需求來建置與部署多個虛擬機器,自由度最高。

所以我們可以從上面得到一個表格:

比較的項目共享主機
Shared Hosting
虛擬私人主機
Virtual Private Server
實體主機
Dedicated Server
自由度?較高最高
資源共享?高,且資源會隨著鄰居而有影響較低,資源都是在一個既定空間上,自己使用無此問題
費用?較低較高
虛擬化技術?無,完全是一個放置網頁專案空間中,可以自行使用配置的資源與空間
效能?較低較高

雲端運算平台

在講雲端運算平台前,需要先知道雲端運算架構圖

首先,我們先從上述的架構圖中的最底層開始。

  • IaaS,指的是「基礎設施即服務」,由Wiki介紹可以知道:
    • 是提供消費者處理、儲存、網路以及各種基礎運算資源,以部署與執行作業系統或應用程式等各種軟體。
    • 可以控制作業系統、儲存裝置、已部署的應用程式,有時也可以有限度地控制特定的網路元件。
    • 與 PaaS 的區別是,用戶需要自己控制底層,實現基礎設施的使用邏輯。
    • 有提供IaaS的服務有:
      1. Amazon EC2
      2. Linode
      3. DigitalOcean
      4. OpenStack
      5. Azure Computing machine
      6. IBM Cloud resource computing machine
  • PaaS,指的是「平台即時服務」,由Wiki可以知道有幾個特點:
    • 提供使用者將雲端基礎設施部署與建立至用戶端
    • 藉此獲得使用程式語言、程式庫與服務
    • 使用者不需要管理與控制雲端基礎設施(包含網路、伺服器、作業系統或儲存)
    • 但是需要控制上層的應用程式部署與應用代管的環境
    • 將軟體研發的平台做為一種服務,以軟體即服務(SaaS)模式交付給用戶
    • PaaS的出現可以加快SaaS的發展,尤其是加快SaaS應用的開發速度
    • PaaS 提供軟體部署平台(runtime),抽象掉了硬體和作業系統細節,可以無縫地擴充(scaling)。
    • 開發者只需要關注自己的業務邏輯與開發,不需要關注底層。
    • 下面這些都屬於 PaaS。
      1. Heroku
      2. RedHat OpenShift
      3. Google App engine
      4. Amazon Elastic Beanstalk
      5. Azure Web App
  • SaaS,「軟體即時服務」,其特性如下:
    1. 在交付模式中雲端集中式代管軟體及其相關的資料,軟體僅需透過網際網路,而不須透過安裝即可使用。
    2. 用戶通常使用精簡用戶端經由一個網頁瀏覽器來存取軟體即服務。
    3. 建立與部署在PaaS上的服務。

雲端運算平台與傳統主機供應商比較

比較項目傳統主機供應商雲端運算平台服務
種類?有共享主機(Shared hosting)
有VPS(Virtual private server)
實體主機(dedicated server)
IaaS
PaaS
SaaS
價格?共享主機最便宜
VPS適中
實體主機較貴
IaaS較貴
PaaS適中
SaaS看提供服務廠商,通常比上述兩者便宜
開發者專注?除了共享主機,其他都需要再花額外的力氣做建置系統建置IaaS需要花額外力氣
利用PaaS部署可以花較多時間在SaaS做開發
服務效率?VPS與實體主機較好IaaS運算較高,但是需要自行調整
PaaS運算度隨著方案選擇做變動
SaaS取決於PaaS方案而變動表現

結論

有此可見,下列要點有:

  • 雲端運算會比一般傳統主機供應商要來的有優勢
    • 主要是把服務與運算資源機器切離,讓開發者可以專心在服務的開發與部署
    • 相關機器的設定與係數的優化就交給雲端運算平台的服務廠商或是專職的DevOps建置的IaaS就好
    • 盡量讓開發者少碰基礎設施運算中的設定越好,以便增加開發上的效率

參考資料

  • https://zh.wikipedia.org/wiki/%E5%9F%BA%E7%A4%8E%E8%A8%AD%E6%96%BD%E5%8D%B3%E6%9C%8D%E5%8B%99
  • https://zh.wikipedia.org/wiki/%E5%B9%B3%E5%8F%B0%E5%8D%B3%E6%9C%8D%E5%8A%A1
  • https://zh.wikipedia.org/wiki/%E8%BD%AF%E4%BB%B6%E5%8D%B3%E6%9C%8D%E5%8A%A1

那些在MySQL上的分區方式

前言

最近因緣際會之下,有一個與能源相關的研究案,需要處理將近2億筆的資料,如果只做到用SQL做查詢的時候,把常搜尋的欄位加入index索引,或是避免一些欄位重複,加入的主鍵primary key。

上述這些方式在資料量大的時候,容易產生一些瓶頸,因為利用BTree概念所作的索引是有搜尋的極限。

為了增加查詢的速度,我們可以考慮的方式如下:

  • 依照年度劃分出個別的資料表
  • 每個年度的資料表用月份為單位劃分成多個分區,總計是12個分區

分區的好處如下:

  • 在資料表中做查詢的時候,可以指定分區,那只會找指定分區中的資料,而不會整張資料表做查詢,進而加快查詢的速度
  • 在分區資料表中,可以允許我們指定那個分區進行刪除資料的動作
  • 從MySQL 5.6之後,可以允許我們指定一個或多個分區中找尋我們要的資料
  • 使用了分區之後,也會影響對資料修改相關的SQL語法,包含: DELETE, INSERT, REPLACE, UPDATE, and LOAD DATA, LOAD XML等

本文章,利用MySQL上面的分區功能實踐查詢的速度。

分區種類介紹

在講分區之前,我們可以從上面的示意圖知道,分區可以在Web應用程式在存取某個大張資料表的時候,先利用分區進行找尋範圍縮小的功能,接著在從指定的分區中尋找我們要的資料出來。分區的方式種類如下:

RANGE Partitioning

範圍分區,指的是自己定義某一個欄位,像是日期這種,就可以定義範圍做分區。

比如說,我們有一個2018 年整年的電量資料表叫做electric,裡面有電號,測量時間,測量的值等。所以依照敘述,我們可以建立出下面的資料表:


CREATE TABLE `electric_data_2018` (
`electricID` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '電號',
`date` datetime NOT NULL COMMENT '當下測量用電時間',
`mwh` double DEFAULT NULL COMMENT '用電量,單位wh'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='1000戶各用戶各時段用電量';

那我們可以利用測量的時間做分區,分區呈現的方式如下12個分區:

  • 2018-01-01到2018-01-31,即是「小於」2018-02-01 00:00:00
  • 2018-02-01到2018-02-28,即是「小於」2018-03-01 00:00:00
  • 2018-03-01到2018-03-31,即是「小於」2018-04-01 00:00:00
  • 2018-04-01到2018-04-30,即是「小於」2018-05-01 00:00:00
  • 2018-05-01到2018-05-31,即是「小於」2018-06-01 00:00:00
  • 2018-06-01到2018-06-30,即是「小於」2018-07-01 00:00:00
  • 2018-07-01到2018-07-31,即是「小於」2018-08-01 00:00:00
  • 2018-08-01到2018-08-31,即是「小於」2018-09-01 00:00:00
  • 2018-09-01到2018-09-30,即是「小於」2018-10-01 00:00:00
  • 2018-10-01到2018-10-31,即是「小於」2018-11-01 00:00:00
  • 2018-11-01到2018-11-30,即是「小於」2018-12-01 00:00:00
  • 2018-12-01到2018-12-31,即是「小於」2019-01-01 00:00:00

那以SQL方式建立帶有分區資料表方式如下:


ALTER TABLE `electric_data_2018`
PARTITION BY RANGE (TO_DAYS(`date`))
(
PARTITION p_201802 VALUES LESS THAN (TO_DAYS('2018-02-01 00:00:00')),
PARTITION p_201803 VALUES LESS THAN (TO_DAYS('2018-03-01 00:00:00')),
PARTITION p_201804 VALUES LESS THAN (TO_DAYS('2018-04-01 00:00:00')),
PARTITION p_201805 VALUES LESS THAN (TO_DAYS('2018-05-01 00:00:00')),
PARTITION p_201806 VALUES LESS THAN (TO_DAYS('2018-06-01 00:00:00')),
PARTITION p_201807 VALUES LESS THAN (TO_DAYS('2018-07-01 00:00:00')),
PARTITION p_201808 VALUES LESS THAN (TO_DAYS('2018-08-01 00:00:00')),
PARTITION p_201809 VALUES LESS THAN (TO_DAYS('2018-09-01 00:00:00')),
PARTITION p_201810 VALUES LESS THAN (TO_DAYS('2018-10-01 00:00:00')),
PARTITION p_201811 VALUES LESS THAN (TO_DAYS('2018-11-01 00:00:00')),
PARTITION p_201812 VALUES LESS THAN (TO_DAYS('2018-12-01 00:00:00')),
PARTITION p_201901 VALUES LESS THAN (TO_DAYS('2019-01-01 00:00:00')),
PARTITION p_max_future_dates VALUES LESS THAN MAXVALUE
);

  • 上述建立分區的意思就是,把「測量日期」欄位轉變成距離year 0有多少天數,將日期轉變成數字之後,我們就可以利用這個天數來進行所謂範圍分區的動作。
  • 其中,…..LESS THAN…..就是小於的意思,舉例來說,第一個分區指的是1月所有電量資料,則小於「2018-02-01 00:00:00」即是這個意思。
  • 當然,只要可以將天數轉換成數字當作範圍,都可以用來進行範圍分區,所以我們也可以轉換成UNIX TIMESTAMP的值做範圍分區。相關建立此分區方式如下:

ALTER TABLE `electric_data_2018`
PARTITION BY RANGE (UNIX_TIMESTAMP(`date`))
(
PARTITION p_201802 VALUES LESS THAN (UNIX_TIMESTAMP('2018-02-01 00:00:00')),
PARTITION p_201803 VALUES LESS THAN (UNIX_TIMESTAMP('2018-03-01 00:00:00')),
PARTITION p_201804 VALUES LESS THAN (UNIX_TIMESTAMP('2018-04-01 00:00:00')),
PARTITION p_201805 VALUES LESS THAN (UNIX_TIMESTAMP('2018-05-01 00:00:00')),
PARTITION p_201806 VALUES LESS THAN (UNIX_TIMESTAMP('2018-06-01 00:00:00')),
PARTITION p_201807 VALUES LESS THAN (UNIX_TIMESTAMP('2018-07-01 00:00:00')),
PARTITION p_201808 VALUES LESS THAN (UNIX_TIMESTAMP('2018-08-01 00:00:00')),
PARTITION p_201809 VALUES LESS THAN (UNIX_TIMESTAMP('2018-09-01 00:00:00')),
PARTITION p_201810 VALUES LESS THAN (UNIX_TIMESTAMP('2018-10-01 00:00:00')),
PARTITION p_201811 VALUES LESS THAN (UNIX_TIMESTAMP('2018-11-01 00:00:00')),
PARTITION p_201812 VALUES LESS THAN (UNIX_TIMESTAMP('2018-12-01 00:00:00')),
PARTITION p_201901 VALUES LESS THAN (UNIX_TIMESTAMP('2019-01-01 00:00:00')),
PARTITION p_max_future_dates VALUES LESS THAN MAXVALUE
);

若我們要看所有分區名稱在此資料表的資訊,我們可以使用下列的SQL做到。


SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='electric_data_2018';

當然,範圍分區也可以用在數值,比如說,我們可以利用用電量「mwh」這個欄位,將數值區分成下列幾塊:

  • partition p0 ( mwh < 100 )
  • partition p1 ( mwh < 500 )
  • partition p2 ( mwh <1000 )
  • partition p3 ( mwh <1500 )

相關SQL語法就會變成:


ALTER TABLE `electric_data_2018`
PARTITION BY RANGE (`mwh`)
(
PARTITION p0 VALUES LESS THAN (100),
PARTITION p1 VALUES LESS THAN (500),
PARTITION p2 VALUES LESS THAN (1000),
PARTITION p3 VALUES LESS THAN (1500)
);

若我們想要刪除某一個分區,我們可以使用下列的SQL語法做到:


ALTER TABLE electric_data_2018 TRUNCATE PARTITION p0;

LIST Partitioning

清單分區,指的是,假設一張資料表,已經有一個預設的集合,假設如下:

上述表格意思是:

  • 有一個欄位叫做「agent_code」表示這三個城市的代碼
  • City A代碼是1,2,3
  • City B代碼是4,5,6
  • City B代碼是7,8,9,10,11

那用LIST分區所建立SQL語法如下:


CREATE TABLE sale_mast2 (bill_no INT NOT NULL, bill_date TIMESTAMP NOT NULL,
agent_codE INT NOT NULL, amount INT NOT NULL)
PARTITION BY LIST(agent_code) (
PARTITION pA VALUES IN (1,2,3),
PARTITION pB VALUES IN (4,5,6),
PARTITION pC VALUES IN (7,8,9,10,11));

意思是:

  • 將欄位「agent_code」城市代碼當作LIST分區
  • 若代碼1,2,3的放在pA分區名稱中,亦即City A
  • 若代碼4,5,6的方在pB分區中,亦即City B
  • 若代碼7,8,9,10,11放在pC分區中,亦即City C

由上述的分區概念,我們可以知道幾件事情:

  • 使用LIST做分區是指的是那個欄位可以分類成不同的種類/集合

COLUMNS Partitioning

以欄位名稱做分區,指的是,將一組欄位並將裡面的值當作範圍或是集合進行分區的概念,那又可以分成:

  • RANGE COLUMN Partitioning
  • LIST COLUMN Partitioning

RANGE COLUMN Partitioning

我們可以直接看下列的SQL語法範例:


CREATE TABLE table3 (col1 INT, col2 INT, col3 CHAR(5), col4 INT)
PARTITION BY RANGE COLUMNS(col1, col2, col3)
(PARTITION p0 VALUES LESS THAN (50, 100, 'aaaaa'),
PARTITION p1 VALUES LESS THAN (100,200,'bbbbb'),
PARTITION p2 VALUES LESS THAN (150,300,'ccccc'),
PARTITION p3 VALUES LESS THAN (MAXVALUE, MAXVALUE, MAXVALUE));

  • 我們建立一個資料表叫做「table3」,而裡面的欄位分別有:「col1」,「col2」,「col3」與「col4」
  • 前三個欄位分別依序排列成col1, col2, clo3並在每一個分區作為一組
  • 每一個值列表使用定義好的條件進行用值當作範圍的分區
  • 篩選的時候,裡面資料的欄位順序需要相同

LIST COLUMNS partitioning

跟先前的「list partitioning」有點類似,不過這是以「COLUMNS」欄位做它配的欄位列表分區。我們城市代碼列表如下:

我們可以從下面SQL語法知道:


CREATE TABLE salemast ( agent_id VARCHAR(15), agent_name VARCHAR(50),
agent_address VARCHAR(100), city_code VARCHAR(10))
PARTITION BY LIST COLUMNS(agent_id) (
PARTITION pcity_a VALUES IN('A1', 'A2', 'A3'),
PARTITION pcity_b VALUES IN('B1', 'B2', 'B3'),
PARTITION pcity_c VALUES IN ('C1', 'C2', 'C3', 'C4', 'C5'));

  • 首先,先建立一個叫做「salemast」的資料表,欄位裡面包含了帳單ID,帳單的地址,名稱城市代碼等
  • 建立三種不同的分區,每個分區分別代表三個城市,因為每一個城市代碼會有不同但是有類似,那就可以用這種方法,利用城市代碼用來「LIST COLUMN Partitioning」

除了使用欄位有城市代碼之外,也可以使用欄位有「DATE」或是「DATETIMESTAMP」的型別來做「LIST COLUMN Partitioning」分區

我們用上述的「electric_data_2018」資料表當作例子,那分區的定就可以改成:


ALTER TABLE `electric_data_2018`

PARTITION BY RANGE COLUMNS (`date`)

(

PARTITION p_201802 VALUES LESS THAN ('2018-02-01 00:00:00'),

PARTITION p_201803 VALUES LESS THAN ('2018-03-01 00:00:00'),

PARTITION p_201804 VALUES LESS THAN ('2018-04-01 00:00:00'),

PARTITION p_201805 VALUES LESS THAN ('2018-05-01 00:00:00'),

PARTITION p_201806 VALUES LESS THAN ('2018-06-01 00:00:00'),

PARTITION p_201807 VALUES LESS THAN ('2018-07-01 00:00:00'),

PARTITION p_201808 VALUES LESS THAN ('2018-08-01 00:00:00'),

PARTITION p_201809 VALUES LESS THAN ('2018-09-01 00:00:00'),

PARTITION p_201810 VALUES LESS THAN ('2018-10-01 00:00:00'),

PARTITION p_201811 VALUES LESS THAN ('2018-11-01 00:00:00'),

PARTITION p_201812 VALUES LESS THAN ('2018-12-01 00:00:00'),

PARTITION p_201901 VALUES LESS THAN ('2019-01-01 00:00:00')

);

上述的分區方式就是指:

  • 利用「date」欄位是「datetime」型別,並用LIST COLUMN分區中的「RANGE COLUMN」分區
  • 分區就是「RANGE BY COLUMN」,並以月份做分區,總共分成12個月

HASH Partitioning

HASH分區指的是,利用某一個欄位,把它做內建的MySQL HASH雜湊之後得到的結果,並指定分區個數讓MySQL進行預先分區的動作。SQL範例如下:


CREATE TABLE student (student_id INT NOT NULL,
class VARCHAR(8), name VARCHAR(40),
date_of_admission DATE NOT NULL DEFAULT '2000-01-01')
PARTITION BY HASH(student_id)
PARTITIONS 4;

KEY Partitioning

此種分區方法是HASH分區中裡面的其中一種,主要是用來把主鍵或是設定UNIQUE唯一值的欄位拿去做雜湊之後並透過指定分區的數量分散到那些分區之中。SQL範例如下:


CREATE TABLE table1 ( id INT NOT NULL PRIMARY KEY,
fname VARCHAR(25), lname VARCHAR(25))
PARTITION BY KEY()
PARTITIONS 2;


CREATE TABLE table2 ( id INT NOT NULL, fname VARCHAR(25),
lname VARCHAR(25),
UNIQUE KEY (id))
PARTITION BY KEY()
PARTITIONS 2;

Sub partitioning

子分區,就是把原先的第一層分區,再做細分下去。其SQL範例如下:


CREATE TABLE table10 (BILL_NO INT, sale_date DATE, cust_code VARCHAR(15),
AMOUNT DECIMAL(8,2))
PARTITION BY RANGE(YEAR(sale_date) )
SUBPARTITION BY HASH(TO_DAYS(sale_date))
SUBPARTITIONS 4 (
PARTITION p0 VALUES LESS THAN (1990),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN (2010),
PARTITION p3 VALUES LESS THAN MAXVALUE
);

上述這個分區指的是:

  • 先把銷售日期取得年份,當作第一層分區
  • 接著,再第二層子分區為p0, p1, p2, p3並分成1990, 2000, 2010年份
  • 所以這樣就會有4 * 4 = 16 個分區,即p0, p1, p2, p3各有4個分區

 

參考資料

  • http://acmeextension.com/mysql-table-partitioning
  • https://www.w3resource.com/mysql/mysql-partition.php
  • https://www.w3schools.com/sql/func_mysql_to_days.asp