在雲端時代,資料倉儲的建置和管理變得至關重要。利用 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 管理控制檯。

  1. 首先,從主儀錶板中選擇 EC2 管理控制檯。
  2. 在左側選單中,選擇“映像”下的“AMIs”。
  3. 預設篩選器顯示我們擁有的所有映像。我們需要從下拉選單中選擇“公共映像”。在此練習中,我將使用一家名為 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 例項的可用區域相符。

  1. 建立 EBS 磁碟區並記錄其 ID。
  2. 將 EBS 磁碟區掛載到 EC2 例項上,指定適當的裝置名稱(例如 /dev/sdf)。
  3. 在例項上建立檔案系統:
# 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

詳細步驟解說:

  1. 安裝 AMI 工具:根據 AWS 官方檔案指引安裝 AMI 工具。

    • 安裝過程中的注意事項:

      • 確保按照 AWS 提供的最新指引進行安裝。
      • 正確設定環境變數以便使用 AMI 工具。
  2. 檢查安裝結果:執行 ec2-ami-tools-versionec2-describe-regions 命令以驗證安裝是否正確。

    • 命令執行後的預期結果:

      • 正確顯示 AMI 工具的版本資訊。
      • 正確列出可用的 AWS 地區。
  3. 封裝新的 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 分鐘。

內容解密:

  1. -u 引數指定 AWS 帳戶 ID。
  2. -k-c 引數分別指定私鑰和憑證檔案的位置。
  3. -p 引數指定映像檔的字首名稱。
  4. -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"

內容解密:

  1. -b 引數指定 S3 儲存桶的名稱。
  2. -m 引數指定映像檔的 manifest 檔案路徑。
  3. -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

內容解密:

  1. --name 引數指定 AMI 的名稱。
  2. -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

內容解密:

  1. 程式碼使用 Python 語言編寫。
  2. BackupManager 類別將實作管理 EC2 例項的方法。
  3. 使用了 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()

程式碼解密:

  1. 初始化與 AWS 的連線:使用 Boto 函式庫建立與 AWS 的連線,並讀取設定檔以取得必要的認證資訊和資源 ID。
  2. 啟動 EC2 例項:使用 run() 方法啟動一個新的 EC2 例項,並等待其狀態變為 running
  3. 附加 EBS 磁碟區:將指定的 EBS 磁碟區附加到啟動的 EC2 例項上,並等待其狀態變為 attached
  4. 建構 SSH 命令引數:根據設定檔中的資訊建構 SSH 命令引數,以便遠端執行命令。
  5. 掛載 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 裝置到指定的掛載點。這一步驟確保了備份資料可以被正確存取和使用。