在雲端時代,資料倉儲的建置和管理變得至關重要。利用 Amazon EC2 和 S3 服務,可以快速搭建一個兼具效能和成本效益的資料倉儲解決方案。本文將逐步說明如何設定 EC2 例項、EBS 磁碟區、MySQL 資料函式庫,以及如何建立自訂 AMI 並使用 Boto 程式函式庫實作自動化備份管理。過程中會涵蓋安全群組設定、彈性 IP 和負載平衡器的運用,確保資料的安全性及服務的穩定性。最後,將示範如何使用 Python 和 Boto 函式庫與 AWS 互動,自動化管理 EC2 例項和 EBS 磁碟區,簡化備份流程並提升效率。
使用 Amazon EC2/S3 作為資料倉儲解決方案
彈性區塊儲存(EBS)
彈性區塊儲存(EBS)是一種區塊級別的儲存裝置,可與 EC2 例項配合使用。EBS 卷完全獨立於例項,且在例項終止和銷毀時資料不會丟失。EBS 卷具有高用性和可靠性。
每個 EBS 卷的大小可以從 1GB 到 1TB 不等。您可以將多個卷掛載到單個執行的 EC2 例項。如果需要大於 1TB 的卷,可以使用作業系統工具(如 LVM)將多個 EBS 卷合併成一個更大的卷。
由於 EBS 卷是區塊裝置,因此在使用之前必須在其上建立檔案系統。或者,您可以在支援原始裝置存取的應用程式中使用它們作為原始裝置。
Amazon WS 也提供了建立卷快照的功能。卷快照是卷內容的某一時間點的副本。該副本備份到 S3 儲存。您可以根據需要建立任意數量的快照。
第一個快照是卷的完整副本,但後續的快照只記錄上一個快照和當前卷狀態之間的差異。
內容解密:
- EBS是一種獨立於EC2例項的儲存解決方案,確保資料永續性。
- 每個EBS卷可達1TB,支援多卷掛載。
- 需要在EBS捲上建立檔案系統後才能使用,或直接作為原始裝置使用。
- 快照功能允許備份和還原資料,增量快照節省儲存空間。
安全群組
網路存取由安全群組控制,安全群組是一組網路存取規則,類別似於 IPTables 規則集。您可以定義目標網路地址、埠號和通訊協定(如 TCP 或 UDP)。
啟動新例項時,可以為其分配一個或多個安全群組。例如,可以建立一個允許 TCP 存取埠 3306(MySQL 服務埠)的資料函式庫安全群組。當建立新的資料函式庫例項時,選擇此安全群組,以允許外部存取 MySQL 伺服器。
內容解密:
- 安全群組用於控制EC2例項的網路存取。
- 可定義協定、埠和來源IP來控制存取。
- 需要允許SSH存取以便管理和連線到例項。
彈性 IP 和負載平衡器
預設情況下,每個例項都會獲得一個動態分配的公有 IP 地址。對於提供 Web 內容或其他公開服務的伺服器來說,這並不合適。每次重新啟動例項時,都可能獲得不同的 IP 地址。
您可以請求一個彈性 IP 地址,並將其附加到一個 EC2 例項。這樣,您可以為伺服器建立一個 DNS 記錄,而該記錄無需隨時間更改。彈性 IP 的另一個好處是,您可以為其分配容錯移轉例項。這意味著,如果主例項發生故障,IP 將被重新定位到另一個能夠處理請求的例項。
內容解密:
- 彈性IP提供固定的公有IP,適合需要穩定存取的服務。
- 可用於簡單的主備組態,實作容錯移轉。
使用者介面
您可以透過 AWS 管理控制檯管理所有 AWS 服務,該控制檯位於 https://console.aws.amazon.com/console/home。
建立自定義 EC2 映像
現在您已經對 EC2 和 S3 服務有了基本的瞭解,讓我們將這些知識付諸實踐。如您所知,我們需要建立一個 AMI,用於啟動我們的例項。我將向您展示如何根據現有的映像建立自定義 AMI。我們將建立一個 S3 支援的 AMI 映像,因為在我們的案例中,這樣更具成本效益,並且我們不需要例項停止功能。當資料傳輸和處理完成後,我們可以銷毀例項。
重用現有映像
讓我們從選擇現有映像開始。在此練習中,我將使用標準的 Amazon AWS 管理控制檯。
- 首先,從主儀錶板中選擇 EC2 管理控制檯。
- 在左側選單中,選擇“映像”下的“AMIs”。
- 預設篩選器顯示我們擁有的所有映像。我們需要從下拉選單中選擇“公共映像”。在此練習中,我將使用一家名為 RightScale 的公司建立的 CentOS 6.5 映像。這是一家在雲環境中佈署關鍵任務系統方面頗有名氣的公司,因此他們提供的映像值得信賴。我們要查詢的 AMI ID 是 ami-2e32c646。我們可以使用篩選器中的搜尋欄位找到它。
此圖示展示了在AWS管理控制檯中選擇AMI進行克隆的步驟。
內容解密:
- 本文介紹如何透過AWS管理控制檯選擇和啟動現有的AMI。
- 描述了查詢特定AMI(CentOS 6.5)的步驟,並強調了使用知名公司提供的映像的好處。
- 圖表清晰地展示了操作流程,每一步驟都與文字描述相符。
在 Amazon EC2/S3 上建置資料倉儲解決方案
建立與設定 EC2 例項
首先,我們需要在 Amazon EC2 上建立一個虛擬伺服器例項。建立例項時,務必選擇適當的 Amazon Machine Image(AMI),例如 CentOS 6.5。確保在建立安全群組時開啟必要的連線埠,包括 3306(MySQL)和 22(SSH),以允許從所有 IP 位址進行存取。同時,生成一個金鑰對並下載私鑰檔案至本地機器,妥善儲存此檔案。
連線至 EC2 例項
一旦例項進入執行狀態,我們就可以使用 SSH 連線至該例項。首先,記錄例項的公用 DNS 名稱,然後使用以下命令進行連線:
$ ssh -i <金鑰對名稱>.pem root@<例項公用 DNS>
修改與設定 EC2 例項
安裝必要的套件
我們需要安裝 MySQL 伺服器等必要的套件。使用 Yum 安裝程式來安裝所需的套件:
# yum install mysql mysql-server
如果需要安裝特定版本的 MySQL,可以先新增 MySQL 的 repository 設定:
# yum install http://repo.mysql.com/mysql-community-release-el6-5.noarch.rpm
建立與設定 Elastic Block Store(EBS)磁碟區
接下來,我們需要建立一個新的 EBS 磁碟區,並將其掛載到 EC2 例項上。確保所分配的空間足夠儲存資料,並且該磁碟區的可用區域與 EC2 例項的可用區域相符。
- 建立 EBS 磁碟區並記錄其 ID。
- 將 EBS 磁碟區掛載到 EC2 例項上,指定適當的裝置名稱(例如
/dev/sdf)。 - 在例項上建立檔案系統:
# mke2fs -F -j /dev/xvdf
# e2label /dev/xvdf mysqlvol
設定 MySQL 例項
修改 MySQL 設定檔(位於 /etc/my.cnf),將資料檔案和 socket 檔案存放在 EBS 磁碟區上:
[mysqld]
datadir=/mysql-db
socket=/mysql-db/mysql.sock
user=mysql
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
啟動 MySQL 服務並設定密碼
啟動 MySQL 服務,並設定 root 使用者的密碼:
# chkconfig --levels 235 mysqld on
# service mysqld start
# mysqladmin -u root -S /mysql-db/mysql.sock password '密碼'
# mysql -p -S /mysql-db/mysql.sock
在 MySQL 中授權 root 使用者遠端存取的許可權:
mysql> grant all privileges on *.* to 'root'@'%' identified by '密碼' with grant option;
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
最後,關閉 MySQL 服務並解除安裝 EBS 磁碟區:
# service mysqld stop
# umount /mysql-db
建立新的 AMI
完成所有必要的修改後,我們可以將目前的 EC2 例項封裝成一個新的 AMI。首先,需要在 Linux 例項上安裝 AMI 工具,並檢查安裝是否成功:
# ec2-ami-tools-version
# ec2-describe-regions
詳細步驟解說:
安裝 AMI 工具:根據 AWS 官方檔案指引安裝 AMI 工具。
安裝過程中的注意事項:
- 確保按照 AWS 提供的最新指引進行安裝。
- 正確設定環境變數以便使用 AMI 工具。
檢查安裝結果:執行
ec2-ami-tools-version和ec2-describe-regions命令以驗證安裝是否正確。命令執行後的預期結果:
- 正確顯示 AMI 工具的版本資訊。
- 正確列出可用的 AWS 地區。
封裝新的 AMI:使用 AMI 工具將修改後的 EC2 例項封裝成新的 AMI。
封裝過程中的關鍵步驟:
- 確保所有必要的修改均已完成並測試透過。
- 使用正確的命令和引數進行封裝。
透過上述步驟,我們可以在 Amazon EC2/S3 上成功建置一個資料倉儲解決方案,並建立一個可重複使用的 AMI 以便於未來佈署。
使用 Amazon EC2/S3 作為資料倉儲解決方案
準備 X.509 憑證及環境變數
在建立自訂的 Amazon Machine Image (AMI) 之前,我們需要準備 X.509 憑證檔案並設定相關的環境變數。這些憑證和變數將用於映像檔封裝命令的執行。首先,從 AWS 帳戶管理控制檯下載 X.509 憑證檔案(包括憑證檔案和私鑰),並將其儲存為 pk.pem(私鑰)和 cert.pem(憑證)。接著,將這兩個檔案複製到執行中的 EC2 例項的 /mnt/ 目錄下。
設定環境變數
在 EC2 例項的 shell 命令列中,設定以下環境變數:
export AWS_USER=<12 位數帳戶 ID>
export AWS_ACCESS_KEY=<REST 存取金鑰>
export AWS_SECRET_KEY=<REST 私密存取金鑰>
這些值可以從 AWS 帳戶管理網頁中取得。
封裝執行中的例項
準備就緒後,使用以下命令封裝執行中的例項:
# ec2-bundle-vol -u $AWS_USER -k /mnt/pk.pem -c /mnt/cert.crt -p CentOS-6.5-x86_64-mysql -r x86_64
這個過程可能需要長達 10 分鐘。
內容解密:
-u引數指定 AWS 帳戶 ID。-k和-c引數分別指定私鑰和憑證檔案的位置。-p引數指定映像檔的字首名稱。-r引數指定映像檔的架構(此例中為 x86_64)。
上傳映像檔至 S3
封裝完成後,將映像檔上傳至 S3 儲存桶:
# ec2-upload-bundle -b pro-python-system-administration -m /tmp/CentOS-6.5-x86_64-mysql.manifest.xml -a "$AWS_ACCESS_KEY" -s "$AWS_SECRET_KEY"
內容解密:
-b引數指定 S3 儲存桶的名稱。-m引數指定映像檔的 manifest 檔案路徑。-a和-s引數分別指定 REST 存取金鑰和私密存取金鑰。
註冊新的 AMI
上傳完成後,註冊新的 AMI:
# ec2-register --name 'pro-python-system-administration/CentOS-6.5-x86_64-mysql' pro-python-system-administration/CentOS-6.5-x86_64-mysql.manifest.xml -K /mnt/pk.pem
內容解密:
--name引數指定 AMI 的名稱。-K引數指定私鑰檔案的位置。
使用 Boto Python 模組控制 EC2
Boto 是 Amazon Web Services (AWS) 的 Python 程式函式庫,提供了對多項 AWS 服務的介面,包括 EC2、S3 和 SQS。
安裝 Boto
在 Fedora 系統上,可以使用以下命令安裝 Boto:
$ sudo yum install python-boto
也可以從專案首頁下載原始碼:https://github.com/boto/boto。
設定組態變數
Boto 的組態檔案 .boto 包含了 AWS 存取金鑰和私密存取金鑰:
[Credentials]
aws_access_key_id = <存取金鑰>
aws_secret_access_key = <私密存取金鑰>
應用程式特定的組態儲存在 backup.cfg 檔案中,使用 ConfigParser 程式函式庫讀取。
初始化 EC2 例項
建立 BackupManager 類別以管理自訂的 EC2 例項。程式碼結構如下(Listing 14-2):
#!/usr/bin/env python
import sys
import logging
import time
import subprocess
內容解密:
- 程式碼使用 Python 語言編寫。
BackupManager類別將實作管理 EC2 例項的方法。- 使用了
logging程式函式庫來記錄應用程式狀態。
使用 Amazon EC2/S3 作為資料倉儲解決方案
自動化備份管理系統的實作
在實作自動化備份管理系統時,首先需要建立與 Amazon Web Services (AWS) 的連線。以下是一個使用 Python 和 Boto 函式庫的範例程式碼:
import boto
import boto.ec2
from ConfigParser import SafeConfigParser
import MySQLdb
from datetime import datetime
import logging
import time
import subprocess
CFG_FILE = 'backup.cfg'
class BackupManager:
def __init__(self, cfg_file=CFG_FILE, logger=None):
self.logger = logger
self.config = SafeConfigParser()
self.config.read(cfg_file)
self.aws_access_key = boto.config.get('Credentials', 'aws_access_key_id')
self.aws_secret_key = boto.config.get('Credentials', 'aws_secret_access_key')
self.ec2conn = boto.ec2.connection.EC2Connection(self.aws_access_key, self.aws_secret_key)
self.image = self.ec2conn.get_image(self.config.get('main', 'image_id'))
self.volume = self.ec2conn.get_all_volumes([self.config.get('main', 'volume_id')])[0]
self.reservation = None
self.ssh_cmd = []
def _start_instance(self):
self.logger.debug('Starting new instance...')
self.reservation = self.image.run(key_name=self.config.get('main', 'key_name'),
security_groups=[self.config.get('main', 'security_grp')],
placement=self.volume.zone)
instance = self.reservation.instances[0]
while instance.state != u'running':
time.sleep(60)
instance.update()
self.logger.debug("instance state: %s" % instance.state)
self.logger.debug("Instance %s is running and available at %s" % (instance.id, instance.public_dns_name))
def _attach_volume(self, volume=None):
if not volume:
volume_to_attach = self.volume
else:
volume_to_attach = volume
instance_id = self.reservation.instances[0].id
self.logger.debug("Attaching volume %s to instance %s as %s" % (volume_to_attach.id, instance_id, self.config.get('main', 'vol_device')))
volume_to_attach.attach(instance_id, self.config.get('main', 'vol_device'))
while volume_to_attach.attachment_state() != u'attached':
time.sleep(20)
volume_to_attach.update()
self.logger.debug("volume status: %s", volume_to_attach.attachment_state())
time.sleep(10) # give it some extra time
self.logger.debug("Finished attaching volume")
def _init_remote_cmd_args(self):
key_file = "%s/%s.pem" % (self.config.get('main', 'key_location'), self.config.get('main', 'key_name'))
remote_user = 'root'
remote_host = self.reservation.instances[0].public_dns_name
remote_resource = "%s@%s" % (remote_user, remote_host)
self.ssh_cmd = ['ssh', '-o', 'StrictHostKeyChecking=no', '-i', key_file, remote_resource]
def _mount_volume(self):
self.logger.debug("Mounting %s on %s" % (self.config.get('main', 'vol_device'), self.config.get('main', 'mount_dir')))
remote_command = "mount %(dev)s %(mp)s && df -h %(mp)s" % {'dev': self.config.get('main', 'vol_device'), 'mp': self.config.get('main', 'mount_dir')}
rc = subprocess.call(self.ssh_cmd + [remote_command])
self.logger.debug('done')
def main():
console = logging.StreamHandler()
logger = logging.getLogger('DB_Backup')
logger.addHandler(console)
logger.setLevel(logging.DEBUG)
bck = BackupManager(logger=logger)
bck._start_instance()
bck._attach_volume()
bck._init_remote_cmd_args()
bck._mount_volume()
if __name__ == '__main__':
main()
程式碼解密:
- 初始化與 AWS 的連線:使用 Boto 函式庫建立與 AWS 的連線,並讀取設定檔以取得必要的認證資訊和資源 ID。
- 啟動 EC2 例項:使用
run()方法啟動一個新的 EC2 例項,並等待其狀態變為running。 - 附加 EBS 磁碟區:將指定的 EBS 磁碟區附加到啟動的 EC2 例項上,並等待其狀態變為
attached。 - 建構 SSH 命令引數:根據設定檔中的資訊建構 SSH 命令引數,以便遠端執行命令。
- 掛載 EBS 裝置:使用 SSH 命令遠端掛載 EBS 裝置到指定的掛載點,並檢查掛載結果。
流程圖示:
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title EC2 S3 資料倉儲建置與自動化備份架構
actor "系統管理員" as admin
package "AWS 雲端環境" {
package "運算資源" {
component [EC2 例項] as ec2 {
[MySQL 伺服器]
[Boto Python]
[備份腳本]
}
component [自訂 AMI] as ami
}
package "儲存資源" {
database [EBS 磁碟區] as ebs {
[MySQL 資料目錄]
[/dev/xvdf]
}
storage [S3 Bucket] as s3 {
[AMI 映像檔]
[備份快照]
}
}
package "網路與安全" {
component [安全群組] as sg {
[SSH Port 22]
[MySQL Port 3306]
}
component [彈性 IP] as eip
component [IAM 角色] as iam
}
package "自動化管理" {
component [BackupManager] as backup {
[啟動例項]
[附加磁碟區]
[掛載裝置]
[執行備份]
}
}
}
admin --> backup : 執行備份腳本
backup --> ec2 : 1. 啟動 EC2 例項
ec2 --> ebs : 2. 附加 EBS 磁碟區
ec2 --> ebs : 3. 掛載至 /mysql-db
ec2 --> s3 : 4. 上傳備份資料
ami --> ec2 : 部署自訂映像
sg --> ec2 : 網路存取控制
eip --> ec2 : 固定公有 IP
iam --> ec2 : 授權 AWS 服務存取
ebs ..> s3 : 建立快照備份
note right of ec2
EC2 例項配置:
- CentOS 6.5
- MySQL 5.x
- Boto Python 模組
- AMI 工具
end note
note right of ebs
EBS 配置:
- 大小: 1GB - 1TB
- 檔案系統: ext3/ext4
- 標籤: mysqlvol
end note
note bottom of backup
自動化備份流程:
1. 讀取配置檔 (backup.cfg)
2. 啟動 EC2 例項
3. 附加 EBS 磁碟區
4. SSH 掛載裝置
5. 執行 MySQL 備份
6. 上傳至 S3
7. 清理資源
end note
note right of s3
S3 儲存策略:
- AMI 映像檔
- 增量快照
- 版本控制
- 生命週期管理
end note
@enduml此圖示展示了自動化備份管理系統的主要流程步驟,包括啟動 EC2 例項、附加 EBS 磁碟區、建構 SSH 命令引數以及掛載 EBS 裝置。
詳細解說:
- 啟動 EC2 例項:此步驟涉及使用 AWS 的
run()方法來啟動一個新的 EC2 例項。該方法需要指定金鑰對名稱和安全群組。此外,還可以指定放置區域,以確保例項在與 EBS 磁碟區相同的區域啟動。 - 附加 EBS 磁碟區:一旦 EC2 例項啟動,就可以將 EBS 磁碟區附加到該例項上。這個過程涉及呼叫
attach()方法,並等待磁碟區的狀態變為attached。 - 建構 SSH 命令引數:為了能夠遠端執行命令,需要建構 SSH 命令引數。這包括指定私鑰檔案、遠端使用者和主機名稱等資訊。
- 掛載 EBS 裝置:最後,使用建構好的 SSH 命令引數來遠端掛載 EBS 裝置到指定的掛載點。這一步驟確保了備份資料可以被正確存取和使用。