Save 37% off PRO during our Black Friday Sale! »

iNDIEVOX 踏入演唱會售票之後的快速蛻變:How we build a scalable PHP website for ticketing

6c910ba730e0acfda9ee450eec9776e6?s=47 fukuball
October 09, 2015

iNDIEVOX 踏入演唱會售票之後的快速蛻變:How we build a scalable PHP website for ticketing

iNDIEVOX 是目前台灣最大的獨立音樂網路商店,主要商業模式是販售高音質數位音樂下載及演唱會售票,除了提供給獨立音樂藝人及音樂廠牌一個完整的數位銷售平台之外,也讓喜歡獨立音樂的大眾可以便利地購買到喜歡的音樂及門票。

我們將在這個議題分享 iNDIEVOX 如何在踏入演唱會售票領域之後開始快速蛻變,慢慢將一個無法 Scale 的 PHP 網站系統改造成如今可以 Scale Up / Scale Out 以承受線上同時上萬人搶票的 PHP 網站系統。

1. 感謝各位的參與,我將在這個議題分享 iNDIEVOX 如何在踏入演唱會售票領域之後開始快速蛻變,慢慢將一個無法 Scale 的 PHP 網站系統改造成如今可以很容易地 Scale Up 以及 Scale Out,目前我們已經是一個可以承受線上同時上萬人搶票的 PHP 網站系統。

2. 好,那跟各位介紹一下我自己,我是林志傑,網路上常用的名字是 Fukuball,所以各位可以用 Fukuball 這個關鍵字找到我。我目前在 iNDIEVOX 獨立音樂網工作,而今天的主題也就是我在 iNDIEVOX 工作的相關經驗分享,相信對同性質或是一些新創網站都會有些幫助。

3. 那麼 iNDIEVOX 究竟是什麼呢?

4. iNDIEVOX 這個網站主要專注於台灣獨立音樂相關的電子商務服務,獨立音樂人可以在這邊上傳他們的作品、或販售演唱會票券,樂迷就可以在這邊直接購買到創作者的數位音樂及演唱會票券,我們希望可以透過這個平台,讓台灣的獨立音樂生態可以像國外的獨立音樂那樣完善。所以大家有空也可以來 iNDIEVOX 上面逛逛、聽聽音樂~

5. 很多人會問,要讓台灣的獨立音樂跟歐美日一樣蓬勃,iNDIEVOX 只做數位音樂及演唱會門票販售這樣夠嗎?

6. 其實,當然不夠。所以我們公司對整個獨立音樂生態系統的完整藍圖是這樣的。iNDIEVOX 目前屬於中子文化集團的一員,我們集團底下還有 StreetVoice、Packer、Blow 等等服務。StreetVoice 主要專注於獨立音樂社群,還未成熟的獨立音樂人可以在這邊發表作品、互相交流,大家可以把 StreetVoice 想成是華人世界的 SoundCloud。而當獨立音樂人的作品更成熟了,我們有 Packer 這個服務來將音樂人的作品發佈到各種線上音樂服務比如 iTunes、Spotify、iNDIEVOX 以及 kkbox、甚至中國的蝦米、百度。而我們公司也會提供各種線下的資源,比如音樂節的演出機會,像是簡單生活節、音樂花房以及見證大團,讓這些獨立藝人可以用線下的方式與歌迷們互動。最後,我們還自創了音樂品牌媒體吹音樂,致力於宣傳獨立音樂相關新聞,而我們目前也是 Yahoo! 音樂及蘋果酷音樂的合作夥伴,在音樂線上媒體這個部分非常有影響力,也因此可以將好的獨立音樂推銷出去。

7. 所以 iNDIEVOX 只是完整獨立音樂生態系統中的一小塊,大家可以把我們網站想成是一個獨立音樂的電子商務平台,所以其他部分我們需要跟其他服務一起合作,這樣我們才可以專注於做好獨立音樂的電子商務。

8. 當然,我們今天只談售票這一塊

9. 給大家看一下 iNDIEVOX 售票系統的現況,我們是從 2011 年開始售票服務的,左邊我列出了這幾年幾個比較重大的熱門活動,紅色標起來的活動是 iNDIEVOX 系統架構有大改變的事件,等一下我就會詳細說明我們做了什麼改變。

10. 在進入正題之前,再次跟大家提醒一下,這個講題並沒有什麼「新的」技術,所以如果各位期待聽到什麼高科技的玩意,可能沒有,這只是我的開發血淚史,以及一些可供參考的經驗。

11. 好,那故事開始了。很久很久以前,那時 iNDIEVOX 還在老闆家的頂樓,我們接到了 iNDIEVOX 史上第一個熱門售票活動

12. 這個事件,iNDIEVOX 內部稱之為「2011 年蘇打粉之亂」!

13. 讓我們看一下當時 iNDIEVOX 售票系統的網站架構。在硬體上,我們只有一台 Server 硬幹,上面裝了 web server 以及 database server。在軟體上,我們沒有使用 Framework,所以原始碼非常亂,很類似大家在第一本 PHP 書上看到的那樣,架構沒有使用 MVC,也沒有 ORM,所以很難維護。

14. 所謂的到處都是 DB Connection 就是這樣,在 Script A 及 Script B 都有可能會有人自己開一個連線來 access database,這在新手剛學 PHP 或沒有使用 Framework 時會常常看到。

15. 所以,當然,我們一開賣就被蘇打粉攻破了.....

16. 經過這次事件之後,我們開始因應蘇打粉之亂來調整網站架構。我們添購了兩台 Server,加上原本的機器,我們就可以有一台機器當 Web Server、一台當 DB Server,然後一台當 Storage Server。所以在硬體上我們可以做到某種程度的分散負載量。在軟體上,由於當時還沒有一個像 Laravel 這樣好用的 Framework,所以我當時就參考了 Rails 來自行研發適合 iNDIEVOX 使用的 Framework,終於把我們的系統改成 MVC 的架構並支援 ORM。在 DB 的連線上也改成使用 Singleton Pattern,不僅增加效能,原始碼的維護也變得容易許多。

17. 使用 Singleton Pattern 來做資料庫連線,大致上的程式架構像這樣。當我們要使用資料庫連線的時候,都是透過 getDBInstance 這個 static method 來取得,這個 method 就會檢查目前是不是已經有資料庫連線存在,如果存在就回傳,如果不存在就進行連線再回傳。這樣大家就可以用統一的方法連進行資料庫連線,在程式上就會比較好維護,然後也不會開太多連線,可以節省資源增加效能。

18. 經過這次的調整之後,我們很辛苦的支撐了一陣子,直到這個事件的發生

19. iNDIEVOX 內部稱之為「2013 年伍粉條之亂」!

20. 其實在經過「2011 年蘇打粉之亂」的調整之後,我心中一直對未來的系統架構有這樣的藍圖,在硬體上,我希望 Web Server 及 DB Server 都可以很容易擴展,只要買了新機器,裝好環境,就可以很容易的加進去整個系統中,增加負載量,然後 Storage Server 的空間可以無上限。在軟體上,Web Appliction 可以很容易複製到各個 Web Server 裡,並且程式碼可以支援資料庫的讀寫分離。整個系統的藍圖就像我右邊畫的這個圖。(稍微說明一下圖)但其實小公司無法一次到位,我們沒辦法一次花個幾百萬買機器來組出這樣的架構,只能一年一年來增加設備,所以這個藍圖一直是個夢。

21. 後來,我看到了 AWS,而且在 2013 年時 AWS 已經相對算是非常成熟的雲端服務,在我自己研究了一陣子之後,就開始說服老闆將所有的系統都搬上 AWS,這樣才有可能可以成功度過伍佰的演唱會搶票。

22. 但要搬上 AWS 還要經過一些前置作業,基本上一定會遇到這三個問題。首先是檔案儲存的問題。原本檔案儲存我們可能都是用 Storage Server 來存放檔案,但如果想要建制一個分散式的系統,在 AWS 上面還是要使用 S3 會是比較好的解決方案。

23. 這段時間我大量修改程式碼,然後將 1T 的檔案搬到了 S3,由於實體機器也還在運作中,所以當時的資料庫是分開的,要特別注意資料庫的同步以及檔案的同步。做完這樣的調整之後,我發現整個系統已經很接近我夢想中的樣子(稍微說明一下圖)。

24. 搬上 AWS 之後,其實就是讓我們從原本使用實體機器時要時時注意的 Performance 改換成注意 Scalability。Performance 就像是有一個很好的小便斗,Scalability 就像是有很多個小便斗一樣!在 AWS 上面可以很容易地做到 Scalability,而 Scalability 又包含 Scale Up 以及 Scale Out。

25. 首先我們來看看 AWS 如何做到 Scale Up。Scale Up 的意思就像右邊的這兩個圖,小便斗由小變大,就是一種 Scale Up。所以 Server 可以很容易的由小變大,就是 Scale Up。

其中 EC2 可以透過 AMI 的方式來做到 Scale Up。AMI 有點像是映像檔,我們可以把運作中的系統包成 AMI,然後就可以用這個 AMI 來開比較大的 EC2 Instance,這樣就做到了 EC2 的 Scale Up。

RDS 則是可以很容易的使用 Modify 的方式,做到 Scale Up,即使不會寫程式,也可以用滑鼠點幾下就完成!

ElastiCache 可以用另開一個比較大的 Instance Node 來做到 Scale Up。

26. 接下來看一下 AWS 如何做到 Scale Out,Scale Out 的意思就像右邊的這兩個圖,小便斗由一個變成多個,就是一種 Scale Out。所以 Server 可以很容易的由一個變成多個,就是 Scale Out。

在 EC2 這邊可以透過 AMI 多開了 EC2 Instance 之後,把這些 Instance 加入 Load Balance 就可以做到 Scale Out 了。

RDS 可以透過 Replication 的方式做到 Scale Out,同樣只要點點滑鼠就可以做到。但是這需要原本撰寫的 PHP Code 也有支援資料庫讀寫分離,才可以真的發揮作用。

ElastiCache 要做到 Scale Out 也很簡單,是就多開一個 Node 就可以了。

27. 我原本以為這樣的調整就可以萬無一失了

28. 沒想到,居然還是被伍粉條攻破了........

29. 檢討這次被伍粉條攻破的原因,其中一點就是我們使用了 AWS 的 Auto Scaling。Auto Scaling 的機制可以設定條件來自動增加 EC2,但是這個增加 EC2 的動作趕不及人潮聚集的速度。EC2 掛到之後,資源無法釋放,拖累 RDS,所以後來資料庫也掛掉。我那時還來不及撰寫資料庫讀寫分離的 PHP Code,所以 RDS 也沒有使用 Replication Scale Out。所以改善的方式就是,將 iNDIEVOX 網站的程式改寫成可以支援讀寫分離,然後熱門活動售票前要事先做好 Scale Up 及 Scale Out,至於要 Scale 到什麼程度,就需要事先人工評估。

30. 這是支援讀寫分離資料庫的程式架構,基本上所有資料庫的存取最終都會來到 DBAccess 這個 class,然後這邊會知道哪些資料庫指令是讀、哪寫指令是寫,它會自動幫我們切換到可以讀或寫的資料庫。大致上會有這幾個重要的 method(稍微說明一下程式碼)

31. 因應伍粉條之亂做完網站架構的調整,主要就是多了資料庫讀寫分離的支援(稍微說明一下圖)。那時 Laravel 還沒有支援資料庫的讀寫分離,所以覺得自己還蠻屌的!

32. 一個月過去,我們馬上又有了一個新的挑戰

33. 這個事件 iNDIEVOX 內部稱之為「2013 年田馥甄的洗禮」!

34. 在田馥甄售票開賣之前,我大量的將資料加上快取。比如單一項目或不會變動的資料像是歌曲、活動、專輯等等資料一律永久快取。然後只要有資料上的更新,也會同時更新快取。所以快取上永遠會是最新的資料,雖然寫入的速度可能會變慢,但讀取的速度因為都在快取上,不會再到資料庫那一層,所以讀取速度變很快。然後會變動的列表資料像是排行榜、新上架列表,就快取 60 秒,60 秒之後就會失效從資料庫讀取最新的列表資料。總之就是可以快取的就快取。

35. 這個是 iNDIEVOX 快取機制的程式範例,所有的 Model Class 可能都會繼承這個抽象類別,基本上這個快取機制的邏輯就跟我上一張投影片所說的那樣,項目資料會永久快取,然後有任何更新就同時更新資料庫及快取。然後列表資料就快取 60 秒。(稍微說明一下程式碼)

36. 經過這個調整之後,整個架構就是多了很多快取,資料庫的 loading 變小,因此效能也增加了。目前整個架構就是 Web、Database 及 Cache 都可以 Scale Up 及 Scale Out,所以只要售票前事先評估好 Scale 量,基本上應該就可以順利應付搶票人潮。

37. 這次完全極致的調整應該就可以萬無一失了吧!

38. 田馥甄演唱會票券開賣之後,人潮達到 EC2 機器的使用上線,所以又被攻破了。我們目前對外公開的 Google Analytics 活躍人數是線上同時 11650 人,但實際的數字更高,我這邊不能透露。

39. 所以經過這次田馥甄的洗禮之後,我們又開始檢討這次售票遇到的問題。首先是 AWS 一個 Region 預設上限只有 20 台 EC2,田馥甄那時用了 20 台 4x.large 的 EC2,但還是超過這些機器的負載量。第二點是第三方金流服務瞬間承載量不夠,許多交易無法完成,造成使用者一直回來重新購票。第三點是讀寫分離在搶票時表現不如預期,因為交易時有太多寫入的操作,所以讀寫分離幾乎無法分散負載量,反而可能在大量切換到 Master 及 Slave 資料庫時增加 loading。

所以改善的方式就是向 AWS 申請使用更多的 EC2,如果購買 AWS Business Support,AWS 可以很快速的處理,讓你可以使用更多的 EC2,有時最快十分鐘之內就會完成。在金流這方面,由於無法指望金流公司可以有更多的負載量,我們可以將付費從購票流程中抽離出來,但 iNDIEVOX 上的主辦單位很堅持訂票時要同時付費,為了應付這種情況,我們研發了一個演算法來實作排隊機制,讓使用者可以分批進入購票流程,減輕金流公司的負載量。然後資料庫方面打到讀寫分離的架構,改用 DynamoDB 來支援售票功能。

40. 在這邊說明一下 iNDIEVOX 如何做到排隊機制。我們會做這個排隊機制主要還是因為主辦單位堅持訂票同時要付費,然後第三方金流又無法承受這個搶票的負載量,所以才使用排隊機制,如果有類似的情境,也可以直接應用這個方法。使用排隊機制,假設每秒可以產生出 500 張訂單,其實 60 秒也可以完成 30000 張訂單,所以沒有什麼缺點。在排隊機制這邊我參考了 Bakery Algorithm 來實做,這個演算法在讀作業系統時應該都看過,我將它稍微修改了一下就完成了我們的排隊機制演算法。最後,如果等待排隊的執行緒太多,有時反而會拖累我們自己的系統,所以到達一個臨界值,我會將使用者導到一個 S3 上面的靜態網頁,讓使用者等待進入購票流程,減少使用者耗掉 EC2 的資源。

41. 這是 iNDIEVOX 的排隊機制等待頁面,使用者會以為還在購票流程中,但其實有更多使用者排在他前面正在付費,有時搶票真的要看速度還有運氣。

42. 然後由於資料庫讀寫分離的架構在搶票時幾乎無用武之地,我拿掉了資料庫讀寫分離的架構,改嘗試使用 DynamoDB 來支援搶票的功能。DynamoDB 是一個很容易擴展且效能很好的 NoSQL Database。它的 Throughput 可以任意調整,比如 Read、Write 可以依據預估每秒 I/O 量來設定,每秒想要完成 10000 張訂單也不是問題,但就是要付很多錢,不過如果是短期的搶票,就很適合使用 DynamoDB。我們可以使用 DynamoDB 來存取售票訂單以及活動的座位表。使用這個方法,比較大的缺點就是讓程式碼變得複雜。不過為了搶票,就還是需要使用到 DynamoDB。

43. 所以在經過了田馥甄的洗禮之後,iNDIEVOX 整個網站的系統架構圖大概就是這樣(稍微說明一下圖)。

44. 這是我們近期一些熱門活動的節錄,像是最近比較熱門的有 08 月的徐懷鈺、07 月的伍佰、06 月的楊丞琳及 SHE 的 Ella,我們都順利的應付了搶票人潮,再也沒有因為搶票而掛站了~

45. 以上就是 iNDIEVOX 踏入售票領域時在系統架構上的快速蛻變,這些架構上的改變,其實現在的 Laravel 5 大部份都可以做得到,所以奉勸大家沒事還是不要自幹框架,否則每次改架構時都會很痛苦!

46. 接下來想跟大家分享一下,如前面所說的,售票前我們必須先預估好 Scale 的量,所以熱門活動售票前我們都需要做一些售票前的準備,接下來就來分享一下這個部份。

47. 在熱門活動售票前,我們會依據以往搶票人數預估此場搶票人數,iNDIEVOX 已累積上萬場售票活動,所以總是可以預估出很接近的數字。這樣的方法很主觀,也許未來累積更多資料,我們也可以嘗試使用 Machine Learning 的方法來幫忙預估搶票的人數。

得出預估的搶票人數之後,我們會計算每個購票步驟的 Request 及 Response 量、每個步驟會使用多少 CPU 及 Memory,還有每個步驟的 Database I/O 量。這牽涉到 EC2 要開幾台,RDS 及 DynamoDB 的 IOPS 要開到多少。然後用這個數字開好機器後,使用 multi thread 的方式模擬搶票,也許跟實際搶票還是會有所不同,但至少可以稍微了解一下到時搶票時的情況。

48. 然後剛剛 iNDIEVOX 最終的系統架構還有一個瓶頸,那就是 EC2 前面的 ELB 以及後面的金流服務。金流服務我們可以用剛剛的排隊機制解決,而 ELB 我們無法直接調整,但是我們可以透過購買 AWS Support 進行 pre-warm 的服務,以增加負載量,這通常需要幾天的作業時間,所以最好可以一個禮拜前就開始準備。要進行 ELB pre-warm 時,會收到一份問券,這時剛剛預估的數字就可以再派上用場。

49. 以上就是今天講題最主要想跟大家分享的部分了,接下來我個人還有一些想法想跟大家分享一下。

50. 有關台灣的售票系統,如果現在問大家覺得做得好不好,目前大家可能還是會說還有許多可以改善的空間,所以我們正在做這件事情。台灣的售票系統有很長期一段時間沒有什麼太大的改變,像是展弈系統的年代、寬宏、華娛等等,宏碁系統的小宇宙、大市集、江蕙賣票等等,還有大家常使用的超商機台,我們一直會在這些系統聽到搶票當機的問題,而我們其實也很想解決這樣的問題,所以 iNDIEVOX、KKTIX 跟拓元雖然表面上競爭關係,但我們私底下也組成了 AWS 賣票同好會,互相交流相關的資訊。

51. 其實售票當機這個問題不是今天才發生,一直以來都有很多因為搶票而當機的新聞,經過這麼多年都還是沒有解決。我們希望這個問題可以在 AWS 賣票同好會得到一個很好的解決方案。

52. 其實 iNDIEVOX 在經歷了田馥甄的洗禮之後就沒再遇過因為搶票而掛站的情形,但是我發現了一個售票定律,那就是「即使沒有當機,報紙還是會寫當機」,因為當機現在已經變成了一個行銷的手段。比如這次徐懷鈺售票,我們大概 30 秒就順利完售,但是新聞就寫「1000多張門票在開賣30秒內秒殺,還造成售票系統大當機」,大家不會覺得這句話很有邏輯問題嗎?如果當機掛站了,到底要怎麼 30 秒內秒殺?

53. 最後跟大家提一下,目前售票服務還是不夠完善,有一些是 iNDIEVOX 無法改變的現況。比如之前提的第三方金流服務瞬間承載量不夠,但主辦單位堅持訂票時同時要付費,如果主辦單位不堅持訂票時同時要付費,我們還可以有更大的承載量。

然後目前 iNDIEVOX 還是有跟 ibon 系統串接,這也造成一些售票瓶頸,實體端點的售票速度絕對比不上網路售票,但有些主辦單位還是會有實體端點的迷思,他會認為實體端點才是銷售的主力,即使目前看到的銷售數字絕大部分都是網路售票。

跟 ibon 系統串接的另一個原因,就是歌迷對實體票券的迷思,有些比較老派的歌迷還是會希望拿到實體票券,而不習慣使用電子票,否則電子票絕對是未來的一個方向。

然後國外對於這種搶票活動,幾乎都是用抽票的方式來解決,但這種方式在台灣並不普及,主辦單位及歌迷對這樣的改變都有疑慮,甚至常常覺得售票系統會有黑箱作業的情況,所以從不考慮這個技術上非常可行的方案。

使用電子票可以解決實體端點瓶頸的很多問題,但目前仍然不夠普及,許多主辦單位不太願意嘗試全電子票的售票方案。

這些問題,其實是因為目前環境的原因,所以我們並無法用自己的技術來解決這些問題,當然未來我們還是會依照主辦單位跟歌迷的習慣慢慢去做調整,讓台灣的售票系統越來越好。

54. 這就是我今天這個講題所有的內容,希望大家都有得到收獲,如果有問題可以現在發問,或者用上面這些方式與我聯繫,目前 iNDIEVOX 也在招募工程師,有興趣的開發者可以加入我們!謝謝!

6c910ba730e0acfda9ee450eec9776e6?s=128

fukuball

October 09, 2015
Tweet

Transcript

  1. iNDIEVOX 踏⼊入演唱會 售票之後的快速蛻變 How we build a scalable PHP website

    for ticketing Fukuball Lin @ PHPConf Taiwan 2015
  2. 關於我 Fukuball / 林志傑

  3. iNDIEVOX 是什麼?

  4. iNDIEVOX 簡介 獨⽴立⾳音樂⼈人 歌迷 Icons made by Simpleicon、Freepik from www.flaticon.com

    ⾼高⾳音質 DRM Free 線上⾳音樂商店! 全台 Live House ⾨門票販售! ⾳音樂社群平台 6000 餘組⾳音樂⼈人! 10000 餘⾸首原創歌曲! 20 餘家 Live House! 各⼤大⾳音樂祭 30 餘萬會員! 100 萬⽉月瀏覽次數! 平均停留時間 17 分
  5. 要讓台灣的獨⽴立⾳音樂跟歐美⽇日! ⼀一樣蓬勃只做這些夠嗎?

  6. StreetVoice Product Family Talent Network > Distribution > Media, Digital

    Music Service Chain Talent Network Distribution Media Pack Promotion TV Shows / Live Events Media Partners Song Placement Online Retailers 我們對獨⽴立⾳音樂! ⽣生態系統的完整藍圖
  7. iNDIEVOX 只是完整獨⽴立⾳音樂! ⽣生態系統中的⼀一⼩小塊

  8. 當然,我們今天只談售票這⼀一塊

  9. iNDIEVOX 售票系統現況 售票⾦金額(單位千萬) 2011 2012 2013 2014 2015 熱⾨門活動⼤大記事 2011/03

    蘇打綠 2011/07 閃靈 … 2012/03 張震嶽 2012/06 徐佳瑩 … 2013/11 伍佰 2013/12 ⽥田馥甄 … 2014/02 ⼩小球 2014/08 ⼋八三夭 … 2015/05 楊丞琳 2015/08 徐懷鈺 … 呈指數型成⻑⾧長
  10. 進⼊入正題之前! ! 各位如果期待聽到什麼⾼高科技的玩意! ! 可能沒有! ! 有的只有我的開發⾎血淚史! ! 及⼀一些可供參考的經驗

  11. 很久很久以前... ! 那時我們還在頂樓⼯工作

  12. 2011! 蘇打粉之亂

  13. 蘇打綠售票時的網站系統架構 • 硬體上:只有⼀一台 Server 硬幹! • 軟體上:沒有使⽤用 Framework,架構沒有使⽤用 MVC、ORM !

    • 到處都是 DB Connection 蘇打粉之亂
  14. 到處都是 DB Connection $mysqli = new mysqli("example.com", "user", "password", “database");

    ! $res = $mysqli-> query("SELECT id FROM example_a ORDER BY id ASC"); $mysqli = new mysqli("example.com", "user", "password", “database"); ! $res = $mysqli-> query("SELECT id FROM example_b ORDER BY id DESC"); Script A Script B 蘇打粉之亂
  15. 當然,被攻破了... 蘇打粉之亂

  16. 因應蘇打粉之亂調整網站架構 • 硬體上:Web Server、DB Server、Storage Server 三台分散負載量! • 軟體上:還沒有 Laravel

    , 所以⾃自⾏行研發 Framework,使⽤用 MVC 架 構、ORM! • Singleton DB Connection 蘇打粉之亂
  17. Singleton DB Connection class DBAccess { private static $db_access; private

    $connection; ! private function __construct() { $this->connection = new PDO( 'mysql:host=example.com;dbname=database', 'user', 'password'); } ! public static function getDBInstance() { if (!self::$db_access || !isset(self::$db_access) || empty(self::$db_access)) { ! self::$db_access = new DBAccess(); ! } return self::$db_access; } } 蘇打粉之亂
  18. 很⾟辛苦的⽀支撐了⼀一陣⼦子...

  19. 伍迷之亂 2013 11⽉月! 伍粉條之亂

  20. 展望未來網站架構 • 硬體上:Web Server 可擴展、DB Server 可擴展、 Storage 無限量! •

    軟體上:Web App 可複製、⽀支援 DB 讀 寫分離 ! • ⼀一年買⼀一台,對⼩小公 司來說,這只是個夢 … … … … 伍粉條之亂
  21. 搬上 AWS! 伍粉條之亂

  22. 搬上 AWS 的前置作業 • 存取檔案要⽤用 S3! - S3cmd https://github.com/s3tools/s3cmd! -

    Flysystem https://github.com/thephpleague/flysystem! • 發信需要⽤用 SES! - Swift Mailer https://github.com/swiftmailer/swiftmailer ! • Session 需要存到 ElastiCache! - 寫個中介軟體可以切換 Session 存到 File / Memcached / Redis 伍粉條之亂
  23. 伍佰售票時的網站系統架構 • ⼤大量修改程式碼, 搬1T 的檔案到 S3, 注意資料庫的同步, ⼤大概花兩個⽉月時間! • 已經很接近夢想中

    的樣⼦子了! 伍粉條之亂
  24. Scalability Performance Scalability = Scale Up / Scale Out 伍粉條之亂

  25. Scale Up • EC2 可以透過 AMI ⽅方式做到 Scale Up! •

    RDS 可以透過 Modify ⽅方式 做到 Scale Up! • ElastiCache 需要另開⼀一個 Node 來做到 Scale Up 伍粉條之亂
  26. Scale Out • EC2 可以透過 AMI 及 Load Balancer ⽅方式做到

    Scale Out! • RDS 可以透過 Replication ⽅方式做到 Scale Out,但需 要原本撰寫的 PHP Code 也 有⽀支援讀寫分離! • ElastiCache 可以透過加開 ⼀一個 Node 來做到 Scale Out 伍粉條之亂
  27. ⾃自! 由! 擴! 展 萬! 無! ⼀一! 失! !

  28. 居然,被攻破了... 伍粉條之亂

  29. Auto Scaling 的問題 • EC2 Auto Scaling 趕不及⼈人潮聚集的速度! • EC2

    掛掉之後拖累 RDS! • 來不及撰寫⽀支援讀寫分離的 PHP Code,所以 RDS 沒有使⽤用 Replication Scale Out! • 改善⽅方式:改寫成可以⽀支援讀寫分離,售票前事先 Scale Up 及 Scale Out(⼈人⼯工評估) 伍粉條之亂
  30. 讀寫分離資料庫的使⽤用 class DBAccess { public static function switchToMaster(){ // 強制切換到

    Master,有時會需要 } public function connectToMaster(){ // 連線⾄至 Master,當然還是要⽤用 Singleton 實作 } public function connectToSlave(){ // 連線⾄至 Slave,當然還是要⽤用 Singleton 實作 } public function selectCMD(){ // 會依⺫⽬目前的連線去 Select,可能在 Master 或 Slave } public function insertCMD(){ // 會暫時切換到 Master 去 Insert } public function updateCMD(){ // 會暫時切換到 Master 去 Update } public function deleteCMD(){ // 會暫時切換到 Master 去 Delete } } 伍粉條之亂
  31. 因應伍粉條之亂調整網站架構 • ⽀支援讀寫分離!! • 那時 Laravel 還沒 有⽀支援讀寫分離, 覺得⾃自⼰己很屌~ 伍粉條之亂

  32. ⼀一個⽉月過去...

  33. 2013 12⽉月! ⽥田馥甄的洗禮

  34. iNDIEVOX 的快取機制 • 單⼀一項⺫⽬目資料或不會變動的資料如歌曲、活動、專輯 的資訊⼀一律永久快取! • 有任何資料上的更新,同時更新快取! • 會變動列表資料如排⾏行榜、新上架,快取 60

    秒! • 總之,可以快取的就快取 ⽥田馥甄的洗禮
  35. iNDIEVOX 的快取機制程式範例 abstract class ModleRecord{ public function __construct(){ // 可以設定快取引擎

    // 先讀去快取 // 快取沒有就讀取資料庫 // 存資料到快取,期限設永久 } public function save() { // 更新資料庫 // 更新快取,期限設永久 } public function destroy() { // 更新資料庫 // 刪除快取 } public function getList() { // 先讀去快取 // 快取沒有就讀取資料庫 // 存資料到快取,期限設 60 秒 } } ⽥田馥甄的洗禮
  36. ⽥田馥甄售票時的網站系統架構 • 就是增加了很多快 取! • Web、Database 及 Cache 都可以 Scale

    Up 及 Scale Out ! • 售票前需事先評估 Scale 量 ⽥田馥甄的洗禮
  37. 極! 致! 擴! 展 萬! 無! ⼀一! 失! !

  38. 達到上限,被攻破了... 真正的數字不能透露 ⺫⽬目前對外公開的線上活躍⼈人數 ⽥田馥甄的洗禮

  39. ⽥田馥甄售票⾯面臨的問題 • AWS ⼀一個 Region 上限只有 20台 EC2,⽥田馥甄超過上限! • 第三⽅方⾦金流服務瞬間承載量不夠!

    • 讀寫分離在搶票時表現不如預期! • 改善⽅方式:! - 申請使⽤用更多 EC2(購買 AWS Business Support)! - 若主辦單位堅持訂票同時要付費,則使⽤用排隊機制讓部份使⽤用 者進⼊入購票流程 ! - 打掉讀寫分離架構,改⽤用 Amazon DynamoDB ⽀支援售票功能 ⽥田馥甄的洗禮
  40. iNDIEVOX 的排隊機制 • 若主辦單位堅持訂票同時要付費,則使⽤用排隊機制! • 每秒產出 500 張訂單,60 秒也可以完成 30000

    張訂 單! • 使⽤用類似 Bakery Algorithm 來實做排隊機制! • 超過上限的使⽤用者會被導到 S3 的 Static Web Server 做等待 ⽥田馥甄的洗禮
  41. iNDIEVOX 的排隊機制等待⾴頁⾯面 ⽥田馥甄的洗禮

  42. Amazon DynamoDB 可擴展資料庫 • Fast and Scalable NoSQL Database! •

    Throughput 可以任意調整! - Read、Write 可以依據預估每秒 I/O 量設定,每 秒 10000 張訂單也不是問題! - 很貴!! • 存取訂單、存取座位表 ⽥田馥甄的洗禮
  43. 因應⽥田馥甄售票調整網站架構 ⽥田馥甄的洗禮

  44. iNDIEVOX 從此再也沒有搶票掛站 2015/08 那我 2015/08 徐懷鈺 … 2015/07 旺福 2015/07

    ⿈黃玠 … 2015/07 楊乃⽂文 2015/07 Hello Nico … 2015/07 伍佰 2015/06 楊丞琳 … 2015/06 陳昇 2015/06 Ella … 2015/05 滅⽕火器 2015/05 法蘭黛 … 2015/05 岑寧兒 2015/05 蔡健雅 … 2015/05 宇宙⼈人 2015/05 1976 … 2015/04 先知瑪莉 2015/04 何韻詩 … 2015/03 李宗盛 2015/02 徐熙娣 …
  45. 這些架構上的改變,Laravel ⼤大部份都可 以做到,所以⼤大家沒事還是不要⾃自幹框架

  46. 售票前準備

  47. 預估搶票時的負載量,模擬測試 • 依據以往搶票⼈人數預估此場搶票⼈人數,iNDIEVOX 已累 積上萬場售票活動! • 計算每個購票步驟的 Request / Response

    量、CPU、 Memory 使⽤用量、Database I/O 量及每個購票步驟的 Response Size! • 這牽涉到 EC2 要開幾台,RDS 及 DynamoDB 的 IOPS 要開到多少! • 將預估的搶票⼈人數拿來模擬測試負載量,使⽤用 multi thread 的⽅方式模擬搶票 售票前準備
  48. Amazon 服務 pre-warm • 瓶頸剩下 ELB,以及⼀一些外部服務如:⾦金流! • ELB 可以透過購買 AWS

    Support 服務進⾏行 pre- warm! • 會收到⼀一份問券,預估的數字可以再派上⽤用場 售票前準備
  49. 後記

  50. 台灣售票系統 後記 By KKTIX Liang Bin Hsueh

  51. 售票系統當機史 By KKTIX Liang Bin Hsueh 後記

  52. 售票定律! ! 即使沒有當機,報紙還是會寫當機 By 我的觀察 後記 「1000多張⾨門票在開賣30秒內秒殺,還造成售票系統⼤大當機」

  53. iNDIEVOX 無法改變的現況 • 第三⽅方⾦金流服務瞬間承載量不夠,但主辦單位堅持訂 票時同時要付費! • 主辦單位實體端點迷思! • 歌迷實體票券迷思! •

    主辦單位及歌迷對抽票的顧慮! • 電⼦子票券使⽤用仍然不夠普及! • 以上皆⾮非公司本⾝身技術可解決的問題 後記
  54. Q & A iNDIEVOX ⼈人才招募中! 請⾒見 http://www.indievox.com/h/jobs.html Find Me! !

    Twitter @fukuball! Github @fukuball! Facebook @fukuball