Skip to main content

· 4 min read
zaxro

網路規劃

VPC 規劃

在一個或多個 VPC 底下依據產品劃分 CIDR,各產品 server 在 private,nginx 在 public,主要透過 nginx 做轉導,public subnet 主要是 route 出外網會設定到 IgW,且裡面的 server 有對外 ip,那在 private 那邊的 route 在出外網時都透過 NAT.甚至不會出外網!

這邊就看公司對於各環境的規劃!

subnet 規劃

產片就依據 VPC 的 CIDR,每個 Region 的 VPC 會依照用途或者功能規劃數個 Subnet,主要以 Public Subnet, Private Subnet 切分,例如,影音產品的 private 在 10.0.0.0/24,public 在 10.0.168.0/24,電玩產品 private 在 10.0.1.0/24,public 在 10.0.169.0/24,如果大一點公司會分品牌,那區分規則可能會變成用 VPC 直接區分.

public 通常放 web server,AD 等,private subnet 會放後端邏輯 .

security group 規劃

如果機器不多的情況下,就不會特別用 NACL 去規劃子 subnet 的網路流量進出,而是透過 security group 規劃,這時候 sg 規劃通常都會用堆疊的,主要是都規範 ingress(inbound rules)其語法是 允許 ip 網段到我的 server 的哪個 port(ex.3306 TCP 125.227.142.21/32 這樣設定代表允許 ip125.227.142.21 到我這台 server 的 3306 port!),這個是有狀態的,也就是說允許進來,在 response 時也直接允許到達該 ip!

  • default - 主要負責ssh連入以及普遍性的監控軟體連入,ex.Zabbix,prometheus.
# 允許 外面哪些ip連入
77.56.156.77/32 TCP SSH
177.56.156.77/32 TCP SSH
  • container or xx service - 程式邏輯,主要用在後端程式間要互通,可以再進一步分細部網段
10.0.0.0/16 TCP xxx port
  • redis/pika - redis-client 端連入 redis-server 的 inbound rule,會掛在 redis server 那邊
10.0.0.0/16  TCP 6050
  • mysql- mysql-client 端連入 mysql-server 的 inbound rule,會掛在 mysql server 那邊
177.227.142.71/32   TCP 3306
  • nginx - 開啟 nginx inbound 的 rule,對外允許所有 ip 到 443 or 80,對內允許所有內部 ip 跟 port 過來
0.0.0.0/0 TCP 443
0.0.0.0/0 TCP 80
10.0.0.0/16 all traffic

命名規劃

可以基於服務功能,環境,地理位置或服務名稱等做規劃

  1. 服務功能 ex. backend-servers-sg
  2. 環境區分 ex. prod-backend-servers-sg
  3. 地理位置區分 ex. sg-us-east-backend
  4. 基於應用名稱 ex. myapp-backend-sg

小結

規劃 VPC 沒有個一定的答案,如果是為了開發上的方便,可能只會有一個 public subnet 放 nginx,其他 private subnet 雖然有以產品區分網段,但是 security group 是 VPC 內完全互通,並開放特定 port 連入這樣.而之後上正式環境可能就變成用 vpc 切分產品,總言之,這就要看對環境的要求!

info

參考資料

  1. vpc 規劃

· 16 min read
zaxro

這邊接續AWS 網路篇的 lab.

目標:Region 內建立 VPC,並使用 elb 將流量導到兩個不同 AZ 中的 web server,避免因為單一 AZ 故障導致的服務中斷.日常管理透過堡壘機進入 web server 做管理.

AWS EC2 introduction

是 Amazon Web Services(AWS)提供的一種基礎架構即服務(IaaS),它允許用戶在 AWS 雲中啟動和管理虛擬機器(VM),稱為 EC2 實例。使用 EC2,用戶可以獲得可調整的計算資源,包括虛擬機器、存儲、網路帶寬和安全性。

Bastion server

堡壘機的建立用來管控跟紀錄使用者操作,透過本機的私有金鑰以及對應放在堡壘機的公有金鑰連線,連線到堡壘機後,再透過放在堡壘機的私鑰連線到對應在內部資源的公鑰做機台管理,另外,也可以透過 multi-hop 方式,在私鑰只放在本機的情況下,透過堡壘機跳到目標管理機器中.

本篇會將 bastion server 放在 public subnet 底下,會有對外 ip,透過 Igw 跟外界溝通.

info

mac,linux,windows 10 以上主要支援的金鑰檔案格式為*.pem.

windows 9 以前是支援 ppk 格式.

AWS ELB introduction

主要負責流量的反向代理,將流量依據使用者設定導到各台伺服器(Target group),功用整理如下:

  1. 分散眾多 request
  2. 處理 SSL 加密連線
  3. 修復請求錯誤(應付 400 Bad request 等)

不過這幾件事情其實 Nginx 都做得到,另外為避免 Nginx 暴露 IP 被打爆,前面通常也會接其他家 CDN,這樣相比之下用 Nginx+CDN 也是個不錯選項.

因此 Nginx+CDN 跟雲服務商的 load balancer 如何選擇? 使用雲服務商提供的 Load Balancer 的可用性是較高的,且可以應付流量大小變化,個人覺得適用在搶票系統以及其他流量會瞬間暴衝的公司,如果公司流量穩定的話,使用 Nginx+CDN 會是比較好的選項.

AWS 提供 ELB 的選項

aws 提供的 load balancer 由 Elastic Load Balancing(ELB)所提供,至 2023/4/22 共有 4 種 ELB,這邊提供官方把較連結

  • Application Load Balancer(ALB):主要用於處理 HTTP/HTTPS 流量(Layer 7)
  • Network Load Balancer(NLB):主要用於處理 TCP、TLS 和 UDP 流量(Layer 4)
  • Classic Load Balancer(CLB):舊版,很少用到
  • Gateway Load Balancer(GLB): 主要用於處理 NAT 和防火牆等網絡服務,能夠將進入 VPC 的流量分發到多個目的地(Layer 3 Gateway + Layer 4 Load Balancing )

ALB 主要用於第 7 層 Load Balancer,主要轉導 protocol: HTTP, HTTPS,基本上就跟 Nginx 差不多,目前了解,差別在沒有偵測來源 IP 城市(nginx geoip)

會設定的內容:

  • Availability Zone:指定的 VPC Region 跟 ELB 需為同一 Region,該 Region 底下 AZ 的都可用,選擇的 subnet 需要有連接 Igw(route tale 也要有),不然會失效.
  • target group: 主要有對內跟對外兩種設定,如果指定了 VPC 中的目標,那麼就是對內的設定;如果指定了 Public IP 或 DNS,那麼就是對外的設定。對內要設定 listener 選擇接收協議,以及 request 怎麼分散到各 web server.

lab

  1. 建立 KeyPair 公私鑰
  2. 建立 EC2 for web server and bastion server
  3. 設定跳板機 ssh 連線
  4. 建立 target group
  5. 建立 ELB
  6. 啟 HTTP 伺服器
  7. 設定-forward-操作
  8. 設定 HTTPS 做 listener
  9. DONe!

建立 KeyPair 公私鑰

EC2 service -> Network & Security -> Key Pairs ->Create Key Pairs-> choose RSA , .pem(For use with OpenSSH) ->download .pem file

如果不小心把載到本機的.pem 檔私鑰刪除,先前使用的舊金鑰就都要作廢了QQ 沒有恢復方法!

EC2 for web server and bastion server

bastion server 建立在 public subnet,web server 建立在 private subnet 上.

web server 其實也可以放在 public subnet,讓使用者直接透過 EIP 進來,不過如果遇到 ddos 攻擊,很容易 web server 就掛了,所以最好前面要有 elb 或者 cdn 這一層.最後,如果 web server 不對外,只靠 elb 之類轉進來,遇到雲服務廠商的 elb 掛掉,就會要花比較多時間把 web server 放回去對外就是.

security group 部分,注意他 associate 在 VPC 上,VPC 是分 Region 的,所以找不到你先前建立的 security group 的時候,去確認 Region 跟 VPC 是否有選對位置.

bastion server 至少需要允許你的 ip 可以 ssh 連入,且 outbound 可以到所有內網需管控機器(10.0.0.0/16),且要有對外 IP.

web server 因為規劃放在 private subnet 網段,只要 inbound 讓所有內網可以連入(10.0.0.0/16)就好,outbound 則考慮之後會串後端,可以用(10.0.0.0/16),基本上範圍可以在限縮.

規劃用 elb 連到內部兩台 web server,兩台 subnet 都用 private subnet

操作:

EC2 ->instances -> launch instances ->Name(product-resource-purpose-region)ex. ford-ec2-bastion-uw1 -> app and os image(my ami or aws market ,or community AMIs) -> instance type(choose cpu ,memory) ->choose key pair for login-> choose ur vpc,subnet, enable auto-assign public ip -> select security group(default and bastion)-> DONe

tip

注意事項:我自己在設定過程中有時候按一按就會忘掉 Network Settings 那部份,所以提醒開 EC2 跟線上問題排除一樣要注意

  1. 硬體狀態(cpu,記憶體,硬碟)
  2. 網路狀態(防火牆,及網路互通狀況)

設定跳板機 ssh 連線

指令如下,可以用-i 指定私鑰檔案位置

ssh -i "ford.pem" ec2-user@77.77.77.77

也可以到~/.ssh/config 裡面修改資料(可以用 v 開啟視覺化模式,移動光標選擇欲複製的範圍。按下 y 複製選取的文字。移動光標到欲貼上的位置。按下 p 貼上複製的文字。)

Host            ford-bastion
HostName 77.77.77.77
Port 22
User ec2-user
IdentityFile ~/.ssh/ford.pem

以上設定好之後,第一次連線會出現以下訊息.

ED25519 key fingerprint is SHA256:7PkkXMF4y2j71d4HTy4qxVRWm77eBQtT73mf8Mf5MH4.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

這是因為 ssh client 第一次連線 ssh server 時,他會需要使用者去確認是不是要連這台 server,如果 yes,ssh client 端就會把 ssh server 的公鑰用 加到本地~/.ssh/known_hosts 裡面,下次連線會去該檔案驗證是否是已知的 hosts 及公鑰是否符合,如此一來就可以避免中間人攻擊等安全問題.

~/.ssh/known_hosts
54.151.73.235 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHX9fQvFIXuJg3LF8777+51qzM7FymrnPoDrYX1Ezr083gutn/5NZkkslRs8mL+nSEOwcwJQfy/s4t7RK1dYQu4=

multi-hop 設定檔,用以把透過 bastion server,連到 private subnet 的 web server.

Host            ford-bastion
HostName 13.52.247.248
Port 22
User ec2-user
IdentityFile ~/.ssh/ford.pem


Host web01
Hostname 10.0.42.235 # (網頁伺服器 1 的私有 IP)
User ec2-user
IdentityFile ~/.ssh/ford.pem
ProxyCommand ssh ford-bastion -W %h:%p

Host web02
Hostname 10.0.56.218 # (網頁伺服器 2 的私有 IP)
User ec2-user
IdentityFile ~/.ssh/ford.pem
ProxyCommand ssh ford-bastion -W %h:%p

建立 target group

操作:

EC2 -> Load Balancing -> Target Groups -> 這邊適用 EC2 起的服務所以選 instance -> input group name -> input HTTP and 3000 port -> choose VPC -> choose instance ID(Ports for the selected instances)把流量導到指定位置的 3000 port.

這邊設定意思是把 ELB 把 443 流量解密後送到 port 3000 上得 web server,然後依據流量到這兩台 EC2.

建立 ELB

因為是會面向網路的 web server,需要 VPC 及 security group 支援,要做 load balance 需要兩個 AZ 以上.

封包傳遞過程(到 EC2 為例):

request: Client -> Internet -> Elb -> Igw -> public subnet(查 route table) -> Target Group -> EC2

response: EC2 -> public subnet(查 route table) ->Igw -> Internet -> Client

以上面過程知道,要透過 elb 連到 private group 裡的 EC2,中間需要符合幾格條件

  1. public subnet- subnet 需要有 Igw 讓封包可以進來,且 route table 有 desination 0.0.0.0/0 透過 Igw 轉導,並可以識別 local
  2. security group- 機器的 security group 要可以讓外界連入,把流量從 Internet 經 ELB 到 Igw -> public subnet,再透過 public subnet 的 router table 查詢到 private subnet 中的 web server.

本章用 web server,只用 HTTP/HTTPS 協議,所以用 ALB 就行,另外 ELB 是有分 Region 的.

操作:

EC2 -> Load Balancing -> Load Balancers -> input Load balancer name -> scheme: choose internet-facing-> IPV4->choose VPC -> choose Mappings of Two AZ in same Region-> choose security group ->choose Listener and target.

info
  1. scheme 部分有兩個選項:
  • Internet-facing:如果我們要從外網請求的話就要選擇這個選項,記得要到 public subnet,這樣 ELB 才能透過外網的 Igw 近來
  • Internal:這會讓這個 alb 只能在內網使用,就無所謂用 public subnet 還是 private subnet 了。
  1. Listener 部分:可以選 HTTP or HTTPS,如果選 HTTPS 就要選你的憑證要用 AWS Certificate Manager(ACM),IAM,匯入憑證等方式

啟 HTTP 伺服器

在連入的目錄底下建立 index.html,並用以下指令起服務.

python3 -m http.server 3000

設定 forward 操作

ELB 設定後 listener 只有基本的 rule,目前只有一條 If (all match)Request is not otherwise routed to target group.

正常使用情況會是: 你自己的域名(ex. modontou.don69.store)設定到該 ELB,再透過 ELB 依據請求的設定,把請求轉到 Target Group.

可以做的設定:

  • 主機標頭(Host header):域名
  • 路徑(Path):域名後面帶的路徑,ex. /channelHandle
  • HTTP 標頭(Http header):就 http header
  • Http 請求方法(Http request methed):GET、POST…….
  • 查詢字串(Query string):域名帶進去的參數,ex. /?test=123
  • 來源 IP(Source IP):Client 端的 IP

Action 部分有三個:

  1. Forward to: 轉寄,會把符合條件的請求導向設定的 target group,可以設定多個 target group 並且可以設定權重
  2. Redirect to: 重導向,符合條件的域名轉導到設定的域名(HTTP status code: 301,302)
  3. Return fixed response: 固定回傳,符合條件的域名都回覆設定的 http code 或是設定的內文

Group-level stickiness: 意思是在 load balance 過程中,啟用會話保持機制,主要是讓同一 client 透過在 client's browser 端設定 cookie 給 ELB 做辨別,讓 client 端可以持續跟同一台 backend server 做互動.cookie 預設一天到期.

操作:

EC2 -> Load Balancing -> yourLoadBalancer -> Listeners -> click 1 rule(基本上這時候你只有一個 rule)-> Manage rules -> Edit rules ->選 Host Header 加入域名,Add action 部分用 Forward to 你的 Target group.

設定 HTTPS 做 listener

這個要在 ELB 加上 HTTPS 的 listener. 另外 ACM 那邊要加個 wild card 憑證綁你的域名.

tip

ACM 申請要用 wildcard certificate 在申請時一定要用* *.don7.store

因為加解密發生在 ELB,所以 target group 那邊 listen 的 port 就是你前端起服務的 port 就搞定!不用另外設定成 HTTPS.

aws ec2 建立 ami

建立 ami 過程,你的 ec2 可以為運行狀態,或關機狀態,兩者差別在運行狀態創建的 AMI 其數據可能不是實時的,後者因為整個狀態停止,所以數據會有一致性,且是最新狀態!

  • 登入 AWS 管理控制台並進入 EC2 服務。
  • 在左側導覽窗格中,選擇 "實例" 選項。
  • 選擇您要創建 AMI 的 EC2 實例。是否停機再建立 ami 看個人需求.
  • 在選中實例後,點擊上方選單中的 "動作"(Actions)。
  • 在下拉選單中,選擇 image and templates。
  • 選擇 create image,為 AMI 提供一個描述性的名稱和描述,如果你不希望拍攝時重新開機,在 no reboot 那邊一定要勾 Enable.
  • 拍攝快照會跟你確認是否要所有 ebs 都拍(預設會都納入),以及是否 delete on termination.
  • DONe

小結

基本的 EC2 跟 AWS internet 相關設定到這邊,接下來是 RDS,然後把後端程式透過 IaC 方式部署,不要再透過 UI 點擊.

· 8 min read
zaxro

目標

前言,工作中遇到 aws athena 查詢 S3 log 過程中需要先建立 partition,這時候腦中浮現幾個問題.

  1. partition 是什麼?
  2. partition 跟 index 區別?
  3. 什麼時候會需要用到 partition?
  4. 為什麼使用 athena 需要先建立 partition,再執行查詢?

背景須知:

  • .frm 檔案是 MySQL 資料表的結構定義檔案,它存放了資料表的欄位資訊、索引、主鍵、外鍵等等的相關設定。

  • .ibd 檔案是 InnoDB 存儲引擎使用的資料檔案,存放著實際的資料內容。 新建一個表會依據表名出現{表名}.frm,{表名}.ibd.

partition 是什麼?

Partition 則是透過將表分割成多個小的子表(partition),然後將資料分散儲存在不同的 partition 中,以提高查詢效率。通常數據到百萬級別可以考慮用 Partition 區分,例如,你原本一張表裡面放 1~12 月的數據(有日期欄位區分),透過 Partition 將該表分成 1~12 月的 Partition,資料本身仍然存儲在原始表中。Partition 只是一種邏輯上的分類方式,用來提高查詢效率和管理大型資料表

lab

建表指令

CREATE TABLE customer_expenses (
customer_name VARCHAR(50) NOT NULL,
expense_amount DECIMAL(10, 2) NOT NULL,
expense_item VARCHAR(100) NOT NULL,
expense_date DATE NOT NULL
);

切表前檔案長相

-rw-rw---- 1 mysql mysql   691 4月  27 11:33 customer_expenses.frm
-rw-rw---- 1 mysql mysql 65536 4月 27 11:33 customer_expenses.ibd

切表指令

ALTER TABLE customer_expenses PARTITION BY RANGE (MONTH(expense_date)) (
PARTITION p1 VALUES LESS THAN (2),
PARTITION p2 VALUES LESS THAN (3),
PARTITION p3 VALUES LESS THAN (4),
PARTITION p4 VALUES LESS THAN (5),
PARTITION p5 VALUES LESS THAN (6),
PARTITION p6 VALUES LESS THAN (7),
PARTITION p7 VALUES LESS THAN (8),
PARTITION p8 VALUES LESS THAN (9),
PARTITION p9 VALUES LESS THAN (10),
PARTITION p10 VALUES LESS THAN (11),
PARTITION p11 VALUES LESS THAN (12),
PARTITION p12 VALUES LESS THAN MAXVALUE
);

切表後檔案長相,會多一個 par 底下有 12 個子表 ibd

-rw-rw---- 1 mysql mysql  1404 4月  27 11:36 customer_expenses.frm
-rw-rw---- 1 mysql mysql 116 4月 27 11:36 customer_expenses.par
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p10.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p11.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p12.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p1.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p2.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p3.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p4.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p5.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p6.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p7.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p8.ibd
-rw-rw---- 1 mysql mysql 65536 4月 27 11:36 customer_expenses#P#p9.ibd

隨機插入數據指令

INSERT INTO customer_expenses (customer_name, expense_amount, expense_item, expense_date)
SELECT CONCAT('customer', t.n), ROUND(RAND()*1000), CONCAT('item', t.n), DATE('2023-01-01') + INTERVAL ROUND(RAND()*364) DAY
FROM (
SELECT ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n + 1 AS n
FROM (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS ones
CROSS JOIN (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS tens
CROSS JOIN (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS hundreds
CROSS JOIN (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS thousands
) t
LIMIT 100;

共 4500 筆,看行數

SELECT COUNT(*) FROM customer_expenses;
+----------+
| COUNT(*) |
+----------+
| 4500 |
+----------+
1 row in set (0.002 sec)

這時候檔案長相

-rw-rw---- 1 mysql mysql  1404 4月  27 11:36 customer_expenses.frm
-rw-rw---- 1 mysql mysql 116 4月 27 11:36 customer_expenses.par
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p10.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p11.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p12.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p1.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p2.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p3.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p4.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p5.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p6.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p7.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p8.ibd
-rw-rw---- 1 mysql mysql 98304 4月 27 11:43 customer_expenses#P#p9.ibd

對 customer_name 建立 index

 ALTER TABLE customer_expenses ADD INDEX idx_customer_name (customer_name);

這時候檔案長相

总用量 1736
-rw-rw---- 1 mysql mysql 1896 4月 27 11:44 customer_expenses.frm
-rw-rw---- 1 mysql mysql 116 4月 27 11:44 customer_expenses.par
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p10.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p11.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p12.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p1.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p2.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p3.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p4.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p5.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p6.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p7.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p8.ibd
-rw-rw---- 1 mysql mysql 147456 4月 27 11:44 customer_expenses#P#p9.ibd

partition 跟 index 區別?

Partition 通常是用來將表拆分成更小的邏輯部分,例如按照時間區間、地理位置等劃分,以方便管理和提高效率。而 index 通常是用來對某些欄位建立索引,以提高查詢效率。例如,對一個大的用戶表建立使用者名稱的索引,可以讓查詢使用者更快速。

兩者可以根據具體情況相互補充,以達到更好的性能優化效果。

什麼時候會需要用到 partition?

當表過大時,查詢和維護都會變得很慢。使用 partition 可以把一個大表分成多個小表,每個小表的查詢和維護速度都會比大表快,進而提高效能。

為什麼使用 athena 需要先建立 partition,再執行查詢?

因會 athena 建立 partition 不用錢,執行查詢則是用運轉時間計費,透過表建立 partition 可以減少之後查詢的時間,進而達到減少成本效果

小結

以上可以看出,分 partition 後,會出現 par 跟 ibd 子表,而建立 index 會在表前面加個地圖索引的感覺,所以容量會多很多.因為 Index 實際上是另一個結構,用來儲存欄位值和指向相應資料行的指標。

athena 建立 partition 不用錢,執行查詢則是用運轉時間計費,透過表建立 partition 可以減少之後查詢的時間,進而達到減少成本效果.

· 8 min read
zaxro

what is git submodule

將一個 Git 存儲庫作為另一個存儲庫的子模組進行管理。也就是說可以在一個 git repo 底下,同時管理多個 git repo,可以在主代碼庫中輕鬆地管理和更新子模組. 詳細的介紹可以看- Git - submodule 使用教學

when to use

我在工作上遇到的情況是有一個日常維護的主 repo,其中有一隻管理域名的檔案需要程式定期去 review 看域名跟憑證多久到期.目前方法是透過建立一個 git repo 內含有檢查域名的程式,建立 build image 的 CI,每當程市有改動會把程式打包做成 image.然後在主 repo 那邊則會拉取該 image 去做域名的檢查.過程如下:

  1. 子 repo 更新程式並 CI 建立 image
  2. 使用步驟 1 建立的新 image,於主 repo 透過 CI 定時使用最新的 image 執行程式檢查.

這個方式沒啥問題,只是對於一些新人或初次看到這個架構的人而言,會覺得串這兩層很複雜.

所以後來我在自己另外寫檢查證書到期的程式時,就想辦法去改善這個可讀性的問題,因此發現 git submodule 是一個不錯的處理方式. 過程想法如下

  1. 透過 CI,在檢測程式的 repo,透過 git submodule 抓取主 repo 的域名檔案,並用程式檢查.

· 7 min read
zaxro

code

平常寫 code 時候,不會去想序列排列底層的事情,因緣際會下,就學一學吧,以下 code 是跟 AI 學習的,能用 python 這樣在同一個 function 內執行同一個 function,這個事情是真的沒想過,另外整個程式執行過程,他執行的順序,也是很大學習重點!

· 21 min read
zaxro

basic introduction

對資料進行分析,基本上過程大致如以下

  1. 資料收集
  2. 使用工具分析資料
  3. 可視化分析(作圖)
  4. 建模
  5. 解釋結果

網路上資料收集方式有很多,從簡便到麻煩依序大致如以下,如果遇到需要取資料時,可以條列式的篩選找到合適方法.

API < 開發者工具的xhr/fetch解析 < bs4解析html中css跟tag < selenium解析html跟點擊

基本上當然是先從簡單開始 try,假設今天已經取到所需的資料了,它可能是 csv,Json 等格式,接著分析資料步驟就會是pandas上場的時候.

分析資料:常見流程有 數據準備、選取、過濾、聚合、分組、排序、合併、填充缺失值,另外因為他的資料結構也有跟 python 的繪圖工具做整合,也可以搭配使用,常用的繪圖工具如以下.

  • Plotly 和 Bokeh 是基於 JavaScript 的交互式圖表,也支援其他語言 ex.Python,可以創建互動性更強的圖表,如滑塊、下拉選單等。
  • Altair 是基於 Vega-Lite 的 Python 套件,支持將數據轉換為交互式圖表,優點是語法較簡單。
  • Seaborn 則是一個統計圖表套件,專注於統計繪圖,方便使用者進行常見的數據分析和繪圖操作。
  • Matplotlib 是 Python 最早期的繪圖套件之一,功能強大,可以繪製各種圖表,包括條形圖、直方圖、散點圖等等,基本上 Seaborn 是建立在 Matplotlib 之上。
  • Pyecharts 則是中國的一個開源圖表庫,提供了各種各樣的圖表,能夠繪製地圖、關係圖、熱力圖等多種圖表。

數據準備

以下數據是改過後的數據,會作為後面 demo 過程範例,基本上你想得到的數據格式 pandas 都支援了,md 檔,csv,dict,json...

pandas 主要數據結構有

  • Series:一維數據結構,類似於帶有標籤的一維數組,可以容納不同類型的數據。

  • DataFrame:二維數據結構,類似於一個二維數組或一個關聯數據庫表,每列可以有不同的數據類型。

  • Panel:三維數據結構,類似於一個由 DataFrame 對象組成的字典,可以用來表示由多個 DataFrame 對象組成的數據集。

最常會使用到的就是 DataFrame.

· 3 min read
zaxro

常見 datetime 應用

日期介於幾天之間

範例一.日期介於昨日到七天前

資料ticket_detail['result']['close_time']他的字串值是2023-04-17 02:36:55這類,是否屆於昨日到七天前,是就 print yes

format=datetime.now() #<class 'datetime.datetime'>

today = datetime.now().date() #<class 'datetime.date'>

yesterday = today - timedelta(days=1) #<class 'datetime.date'>

seven_days_ago = today - timedelta(days=7) #<class 'datetime.date'>

date_format = "%Y-%m-%d %H:%M:%S" #把字串為2023-04-17 02:36:55依據格式換成datetime.datetime物件

# 使用datetime.strptime方法把字串依據格式換成 datetime.datetime物件,使用date方法變成datetime.date物件進行比較
if seven_days_ago<= datetime.strptime("2023-04-17 02:36:55",date_format).date() <= yesterday:
print("yes")
info

範例二:timedelta 物件運用,憑證是否在今天到 30 天之間到期

# 將到期日期字串轉換為 datetime 格式
vaild_date = datetime.strptime("2023-04-17 02:36:55", date_format)

# 取得當前時間
now_time = datetime.now() #2023-04-17 20:33:01.577635

# 計算到期日期與當前時間的時間差,注意這邊是timedelta物件囉!
vaild_days = vaild_date - now_time

# 印出時間差和時間差的資料型態
print(vaild_days) #-1 day, 6:11:15.206948
print(type(vaild_days)) #<class 'datetime.timedelta'>

# 判斷時間差是否在 當下到 30 天之間到期
if vaild_days > timedelta(days=0) and vaild_days < timedelta(days=30):
print(vaild_days)
print("ok")

tip

注意~

以上面為例,到期時間為"2023-04-17 02:36:55",當下時間為 2023-04-17 20:25:39.793060,這種情況下很明顯到期時間是小於當下時間的,相減結果會是-1 day, 6:03:53.422373.

由此可知,只要前時間小於後時間,剪出來的 day 都會是負數,也就是你的憑證到期了!

另外,如果是 datetime.date 之類物件減去 timedelta 物件,是不會變成 timedelta 物件!

vaild_date=datetime.strptime("2023-04-17 02:36:55",date_format).date()
print(type(vaild_date-timedelta(days=1))) # <class 'datetime.date'>

如果是 datetime.date 之類物件減去 datetime.date 物件,是會變成 timedelta 物件的!

vaild_date=datetime.strptime("2023-04-17 02:36:55",date_format).date()
print(type(datetime.now().date()-vaild_date)) #<class 'datetime.timedelta'>

但如果是 datetime.datetime 之類物件減去 datetime.date 物件會報錯 TypeError: unsupported operand type(s) for -: 'datetime.date' and 'datetime.datetime'

tip

datetime.datetime 同類別可以相減

datetime.date 同類別可以相減

datetime.datetime 之類減去 datetime.date 會報錯

datetime.datetime 跟 datetime.date 都可以減去 timedelta

· 13 min read
zaxro
tip

基本上 Internet 設定相關依序:

  1. 建立 VPC
  2. 建立 public subnet & private subnet(需連結 VPC)
  3. 建立 Internet gateway(需連結 VPC)
  4. (optional)建立 NAT gateway(optional,需連結 subnet,配置 eip,前提是 private subnet 需要連外時)
  5. 建立 route table(設定是否連內網 local,連外 Igw,NAT gateway,VPN gateway,peering 等) 以及要給哪個 subnet 用,一個 route table 可以給多個 subnet 用
  6. 設定 Security group 對服務開啟 ip and port
  7. 網路到這邊,去設定服務囉!

aws internet introduction

一般地端要讓網路進到 server,結構簡單的長這樣

internet -> Router -> Switch -> server

要建立同樣的網路運行環境,在 aws 要透過 Amazon Virtual Private Cloud(VPC),而資源的建立會圍繞 VPC 進行.

VPC

VPC 是 AWS 提供虛擬化網路環境的服務,資源的建立會圍繞 VPC 進行.

VPC 設定注意事項:

  • 多個 VPC 的 CIDR 要確保不重疊:VPC 在 aws 雲上扮演一個網段的角色,所以在創建 VPC 的過程中,需要為 VPC 和子網選擇適當的 IP 範圍.

  • VPC 是綁 region 的: 不同地區的 application 需要綁各自的 VPC.

  • VPC 有 AZ 概念: 設計 VPC 和子網時,請考慮可用區域和容錯能力,在兩個不同 AZ 建立同樣服務,即使其中一個 AZ 的 APP 故障,也可以靠另外一個 AZ 的 APP 提供服務.

  • VPC 間 CIDR 重疊: 如果 CIDR 部分有重疊可能會造成 peering connection 設定上報錯.

subnet

Classless Inter-Domain Routing(CIDR) 將 IP 地址劃分為網絡前綴和主機地址,可以表示一定範圍的 IP(subnet)或者指定特定 IP.

可以將 VPC CIDR 的 IP 地址空間劃分為多個 subnet,每個 subnet 為包含一段連續的 IP 地址的邏輯網絡分區.

私有 IP 範圍級別有三種,從中挑選即可,不過要注意的是 aws 有限制無論哪種級別,一個 VPC 最多就只能有 65536(2 的 16 次方)個 ip.

  • Class A: 10.0.0.0/8,包含 10.0.0.0~10.255.255.255
  • Class B: 172.16.0.0/12,包含 172.16.0.0 ~ 172.31.255.255
  • Class C:192.168.0.0/16,包含 192.168.0.0 ~ 192.168.255.255

因此結合 AWS 限制還有 CIDR 切分,在 aws 配置 VPC 時,用 Class A 每個子網最多有 65536 個 ip,可以切分出最多 256 個 subnet.

如果有一個 192.168.0.0/16 的 B 級網段,需要將一個 IP 地址段分成 8 個子網,可以使用子網掩碼 /19(即 255.255.255.192),這個子網掩碼可以將一個 IP 地址段分成 2^3=8 個子網,每個子網可以分配 2^13=8192 個 IP,但須減去保留網路地址跟廣播地址所以共 8190 個主機 IP 地址(因為要保留網路地址和廣播地址,注意如果在 aws 要保留 5 個,也就是 8187 個 ip 可使用. 詳細計算可以看這篇

public subnet & private subnet

elb 這類對外的服務會需要連結在 public subnet(至少 route table 要有 Igw), database server 這類不需要對外的就會是在 private subnet(route table 不會有 Igw,頂多透過 NAT gateway 連外).

而 Nginx 這類 web server,則依據需求可以放在 public subnet 或者 private subnet,如果前面有用 elb 配合 target group 轉封包進來,放在 private subnet 也可以,但如果不打算用 elb 的話,就需要配置 eip 然後放在 public subnet.

Internet gateway(IGW)

網際網路閘道(IGW) 主要功能是讓服務能跟 internet 通訊,外部網路封包會透過 IGW 跟 VPC 內的資源溝通,這邊 IGW 就像是一台連外的 router,但是外部服務要透過 IGW 進來要找得到機器,機器必需有對外 IP 作為在 internet 上的路由溝通,這個對外 IP 可以選自己綁定的 eip 或則是 aws 隨機派發的外部 ip(每次開機都會變).

但問題來了,要透過 IGW 上網,機器就必須要有對外 ip,內部 server 開啟對外 ip 然後臨時開通連接 IGW,這個過程複雜又不合當初區分內外網設定,因此是 Network Address Translation(NAT)上場的時候了!

Network Address Translation(NAT) gateway

NAT 需要有 eip 綁定,他做的事就是把內部出來的封包,記錄他們的 ip 跟 port 號之後,轉成 eip 跟隨機 port,然後再對外網服務連線,得到 response 後,再依據紀錄表上的資訊做 ip 跟 port 轉換.

這樣做可以使私有子網內的內部資源訪問公網時保持安全和隱私,同時還可以有效地防止來自 Internet 的攻擊。

danger

NAT gateway 是要付費的! 項目包含 elastic IP 跟 NAT gateway.

route table

用於管理子網流量路由的組件。每個 VPC 都有一個主路由表,用於管理其所有子網的流量路由。這就像你在陌生的城市,要透過 google map 去看路牌的標示,才知道路要怎麼走一樣,如果 route table 是空的,那基本上資訊也無法傳遞!

security group & Network Access Control List

  • security group 是 instance 級別的虛擬防火牆,用於控制進出的各種協議的各種流量.
  • Network Access Control List 是 subnet 級別防火牆,也是拿來管流量.

兩者除了級別以外的區別:

  • NACL 是無狀態的(stateless),不跟蹤狀態,也就是要規定 7.7.7.7 能進來(inbound),同時也要規定能出去(outbound),才會放行跟 7.7.7.7 有關的流量.
  • Security group 是有狀態的(stateful),這代表會自動允許出站(outbound)或入站(inbound)的返回流量,舉例來說:如果對外可以連接 7.7.7.7:80,那 7.7.7.7:80 回來的流量也會自動允許. 要注意!7.7.7.7:80 不能自己進來.

lab

  • 目標:Region 內建立 VPC,並使用 elb 將流量導到兩個不同 AZ 中的 web server,避免因為單一 AZ 故障導致的服務中斷.日常管理透過堡壘機(bastion)進入 web server 做管理.本篇主要講網路設定部分,而 elb,EC2 等服務設定會留到下一篇.
  1. 建立 VPC
  2. 建立 public subnet & private subnet(需連結 VPC)
  3. 建立 Internet gateway(需連結 VPC)
  4. (optional)建立 NAT gateway(optional,需連結 subnet,配置 eip,前提是 private subnet 需要連外時)
  5. 建立 route table(設定是否連內網 local,連外 Igw,NAT gateway,VPN gateway,peering 等) 以及要給哪個 subnet 用,一個 route table 可以給多個 subnet 用
  6. 設定 Security group 對服務開啟 ip and port
  7. 網路到這邊,去設定服務囉!

CIDR 規劃

  • CIDR 規劃:VPC 用 10.0.0.0/16.這邊預計只用 4 個 subnet,不過為了保險所以會切出 16 個(2 的 4 次方)所以子網段 CIDR 會是 20,每個 subnet 扣掉 aws 預留的 5 個 ip 還會有 4091 個 ip 可用.
欄位設定值說明
VPC IDford-test-vpc欲建立子網路的 VPC,此例為 sample-vpc
對外子網路 1子網路名稱ford-subnet-public01自訂子網路的名稱
Availability Zoneap-northeast-1a選擇子網路所在的 Availability Zone
IPv4 CIDR 區塊10.0.0.0/20如前面的介紹
對外子網路 2子網路名稱ford-subnet-public02同上
Availability Zoneap-northeast-1c
IPv4 CIDR 區塊10.0.16.0/20
內部子網路 1子網路名稱ford-subnet-private01同上
Availability Zoneap-northeast-1a
Pv4 CIDR 區塊10.0.32.0/20
內部子網路 2子網路名稱ford-subnet-private02
Availability Zoneap-northeast-1c
Pv4 CIDR 區塊10.0.48.0/20

建立 VPC

操作:

VPC -> create VPC -> IPv4 選 manual input -> IPv4 CIDR 10.0.0.0/16 ->無 IPv6 CIDR 區塊.

建立 subnet

操作:

VPC -> Create subnet -> choose VPC ID -> choose AZ -> fill in CIDR of subnet ->done

這邊要依據前面 CIDR 規劃圖要做四個 subnet(兩個 public 兩個 private,CIDR 照上面)

建立 Internet gateway

操作:

VPC -> Internet Gateway ->click on the "Attach to VPC" option in the "Actions" menu. -> select the VPC to attach the Internet Gateway ->done

建立 NAT gateway

因為有兩個 web server 各自要出去要透過各自的 NAT Gateway,這邊的 NAT Gateway 是建立在 public subnet 中歐!

操作:

VPC(verify AZ first) -> NAT Gateways -> Create NAT Gateway -> bind EIP to NAT Gateway -> done and wait for status become available ->associate NAT Gateway with public subnet -> private route table add destination 0.0.0.0/0 to NAT Gateway -> Ensure that the outbound rules in the security group are configured to allow traffic ot targe ip.

danger

NAT 很貴,lab 做完記得要關掉

info

如果開了 NAT gateway,連到 route table,網路還是不通,這時候就分別檢查以下設定

  1. NACL
  2. security group
  3. VM 防火牆

設定 security group 會跟開放使用的協議的有關係,常用的網路測試工具 ping 跟 traceroute 都是走 ICMP 協議,如果你只開 TCP 是不過是正常的.

ICMP 是一種基於 IP 協定的網路協定,它不使用 TCP 或 UDP 協定。ICMP 主要用於網路診斷、錯誤報告和路由選擇。

建立 route table

route table 語法

如果你的 目的地是 10.0.0.0/16,要透過下一站目標 ex. 10.0.0.1 or local(Aws) 幫你送資料出去.

如果你的 目的地是 0.0.0.0/0,要透過下一站目標 Igw 幫你送資料出去.

route table 設定

前面規劃共 2 個 public subnet,2 個 private subnet.public subnet 可以共用一個給 public subnet 使用的 route table,而 private subnet 要兩個 for private subnet 的 route table(差別在 NAT gateway 不同),因此共會建立 3 個 route table.

  • public subnet: 設定 destination 0.0.0.0/0 target 過 IGW,destination 到 10.0.0.0/16,target 是 local(本地端).

  • private subnet1: destination 0.0.0.0/0 而 Target ngw-01.destination 10.0.0.0/16 而 Target local.

  • private subnet2: destination 0.0.0.0/0 而 Target ngw-02 ,destination 10.0.0.0/16 而 Target local.

操作:

VPC(verify AZ first) -> Route tables -> create route table -> done -> edit routes(加 target and destination)->subnet associations

設定 Security group

default:

  • inbound rules: allow Port range:All, Protocol:All Source:10.0.0.0/16

  • Outbound rules: Port range:All, Protocol:All Source:0.0.0.0/0(為了可以把對外資訊透過 NAT 出去), Port range:All, Protocol:All Source:10.0.0.0/16(可以到內部其他 subnet)

forBastion(堡壘機):允許 ssh

  • inbound rules: allow Protocol:ssh Source:YourIp

forElb:允許 HTTP and HTTPS

  • inbound rules: allow 0.0.0.0/0 HTTP,HTTPS 進來.

操作 EC2 -> Network & Security -> Security Groups -> Create security group -> input Security group name , associate VPC -> add inbound and outbound rule.

小結

網路基本設定在這邊,下一篇是有關 EC2 跟 ELB 的設定.

· 8 min read
zaxro

disk management command

在管理上會去檢視硬碟使用量,資料夾資料大小,如果掛硬碟跟卸下硬碟也會有專用 command

df -h: 列出所有已掛載的硬盤的分區信息以及剩餘空間大小,結果長這樣

Filesystem      Size  Used Avail Use% Mounted on
devtmpfs 7.6G 0 7.6G 0% /dev
tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs 7.7G 801M 6.9G 11% /run
tmpfs 7.7G 0 7.7G 0% /sys/fs/cgroup
/dev/nvme0n1p1 100G 6.0G 95G 6% /
/dev/nvme1n1 300G 7.1G 293G 3% /var/gogo
tmpfs 1.6G 0 1.6G 0% /run/user/1000

· One min read
zaxro

gitlab 權限管理

gitlab 有一堆權限管理東東,詳情,透過適當的設計來安全權限給予.

這邊說一下之前遇到的問題,read_repository and read_registry 差別在哪裡!官方解釋對個別解釋如下:

read_registry-Grants read-only (pull) access to a Container Registry images if a project is private and authorization is required. Available only when the Container Registry is enabled.

read_repository-Grants read-only access to repositories on private projects using Git-over-HTTP or the Repository Files API.

小結:read_registry 主要是讓你只能抓 image 下來,read_repository 則是可以檢查 repo 裡面所有分支,commit 等,並可以 clone repository,但不能 push!