跳到主要內容

發表文章

目前顯示的是 11月, 2019的文章

基於Galera Cluster多主結構的Mysql高可用集群

Galera Cluster特點 1、多主架構:真正的多點讀寫的集群,在任何時候讀寫數據,都是最新的 2、同步複製:集群不同節點之間數據同步,沒有延遲,在數據庫掛掉之後,數據不會丟失 3、併發複製:從節點APPLY數據時,支持并行執行,更好的性能 4、故障切換:在出現數據庫故障時,因支持多點寫入,切換容易 5、熱插拔:在服務期間,如果數據庫掛了,只要監控程序發現的夠快,不可服務時間就會非常少。在節點故障期間,節點本身對集群的影響非常小 6、自動節點克隆:在新增節點,或者停機維護時,增量數據或者基礎數據不需要人工手動備份提供,Galera Cluster會自動拉取在線節點數據,最終集群會變為一致 7、對應用透明:集群的維護,對應用程序是透明的 Galera Cluster工作過程 客戶端發送更新指令到mysql服務器,服務器回復OK,但客戶端有可能以事務方式執行,並沒有發送確認指令(commit);當客戶端發送commit指令確認后,mysql服務器會把數據庫的更新複製到同一個集群的其他節點;集群中的所有節點會對數據庫的更新進行校驗,檢查更新完的數據與數據庫中的數據是否衝突,如果不衝突,服務器端會回復OK;如果更新的數據與集群中的任意一個節點數據發生衝突,則都會回復error 實現Galera Cluster集群 至少需要三台機器;並且Galera Cluster也是一個數據庫服務,下載Galera Cluster必須卸載服務器現有的mysql數據庫服務 master1配置 [root@centos7 ~]# vim /etc/yum.repos.d/base.repo #編輯yum源倉庫 [mysql] name=mysql baseurl=https://mirrors.tuna.tsinghua.edu.cn/mariadb/mariadb-10.0.38/yum/centos7-amd64/ gpgcheck=0 enabled=1 [root@centos7 ~]# scp /etc/yum.repos.d/base.repo 192.168.38.37:/etc/yum.repos.d/mysql.repo #發送給另外兩個主節點 [root@centos7 ~]# scp /etc/yum.rep...

性能測試:深入理解線程數,併發量,TPS,看這一篇就夠了

併發數,線程數,吞吐量,每秒事務數(TPS)都是性能測試領域非常關鍵的數據和指標。 那麼他們之間究竟是怎樣的一個對應關係和內在聯繫? 測試時,我們經常容易將線程數等同於表述為併發數,這一表述正確嗎? 本文就將對性能領域的這些關鍵概念做一次探討。 文章可能會比較長,希望您保持耐心看完。   1. 走進開封菜,了解性能 ①老王開了家餐廳 我們的主角老王 ,在M市投資新開業了一家,前來用餐的顧客絡繹不絕: 餐廳里有4種不同身份的人員:   用戶一次完整的用餐流程如下: 顧客到店小二處付款點餐 => 小二將訂單轉發給后廚 => 后廚與備菜工配合,取材完成烹飪后交給小二 => 小二上菜,顧客用餐。 假設所有顧客都不堂食而是打包帶走,也就是不考慮用戶用餐時間。餐廳完成一次訂單的時間是多久?   訂單時間 = 顧客點單時間 + 前台接收轉發時間 + 后廚取材烹飪時間 + 后廚交給服務員,服務員上菜時間。   說白了就是每個流程的耗時相加。 假設以上時間分別為1,1,5,1(分鐘),那麼一次訂單的完成時間就是8分鐘。      ②問題來了 餐廳當然不可能只有一個人就餐,否則老王不要帶着小姨子跑路。 所以我們接下來看多人就餐的情況。 假設同一時間點上有兩人就餐,會發生什麼情況?   第一位用戶與第一個場景一樣,仍然是點單-下單-烹飪-上菜,8分鐘后第一位顧客拿着打包的食物離開。 第二位用戶則有所不同了。假設小二,廚師,備菜都只有一人,而且他們每個人同時只能處理一件事情。 那麼第二位用戶首先需要在點餐時等待小二1分鐘,而後廚師烹飪第一位用戶的菜時,沒有任何人在為他服務。 我們來梳理一下這個過程中,每一分鐘都發生了什麼事情:   可以看到,兩個顧客完成訂單的總時長是13分鐘。 繼續推算我們發現,每增加一人總時長增加5分鐘。 在當前的人員配置下,顧客越多,後來的顧客等待時間就越長。   ③這還不是高峰期 如果餐廳在高峰時段只有兩人用餐,那估計老王還得帶着小姨子跑路。 實際一個運營得當的開封菜餐廳,在用餐高峰時段的顧客數可能...

Python 併發總結,多線程,多進程,異步IO

1 測量函數運行時間 import time def profile(func): def wrapper(*args, ** kwargs): import time start = time.time() func( *args, ** kwargs) end = time.time() print ' COST: {} ' .format(end - start) return wrapper @profile def fib(n): if n<= 2 : return 1 return fib(n-1) + fib(n-2 ) fib( 35 )   2 啟動多個線程,並等待完成   2.1 使用threading.enumerate() import threading for i in range(2 ): t = threading.Thread(target=fib, args=(35 ,)) t.start() main_thread = threading.currentThread() for t in threading.enumerate(): if t is main_thread: continue t.join()   2.2 先保存啟動的線程 threads = [] for i in range(5 ): t = Thread(target=foo, args= (i,)) threads.append(t) t.start() for t in threads: t.join()   3 使用信號量,限制同時能有幾個線程訪問臨界區 from threading import Semaphore import time sema = Semaphor...

CQRS+ES項目解析-Diary.CQRS

在《當我們在討論CQRS時,我們在討論些神馬》中,我們討論了當使用CQRS的過程中,需要關心的一些問題。其中與CQRS關聯最為緊密的模式莫過於Event Sourcing了,CQRS與ES的結合,為我們構造高性能、可擴展系統提供了基本思路。本文將介紹 Kanasz Robert在《Introduction to CQRS》中的示例項目Diary.CQRS。 獲取Diary.CQRS項目 該項目為Kanasz Robert為了介紹CQRS模式而寫的一個測試項目,原始項目可以通過訪問《Introduction to CQRS》來獲取,由於項目版本比較舊,沒有使用nuget管理程序包等,導致下載以後並不能正常運行,我下載了這個項目,升級到Visual Studio 2017,重新引用了StructMap框架(使用nuget),移除了Web層報錯的代碼,並上傳到博客園,可以從這裏下載:Diary.CQRS.rar Diary.CQRS項目簡介 Diary.CQRS項目的場景為日記本管理,提供了新增、編輯、刪除、列表等功能,整個解決方案分為三個項目: Diary.CQRS:核心項目,完成了EventBus、CommandBus、Domain、Storage等功能,也是我們分析的重點。 Diary.CQRS.Configuration:服務配置,通過ServiceLocator類進行依賴注入、服務查找功能。 Diary.CQRS.Web:用戶界面,MVC項目。 這是一個很好的入門項目,功能簡單、結構清晰,概念覆蓋全面。如果CQRS是一個城堡,那麼Diary.CQRS則是打開第一重門的鑰匙,接下來讓我們一起推開這扇門吧。 Diary.CQRS.Web 運行項目,最先看到的是一個Web頁面,如下圖: 很簡單,只有一個Add按鈕,當我們點擊以後,會進入添加的頁面: 我們填上一些內容,然後點擊Save按鈕,就會返回到列表頁,我們可以看到已添加的條目: 然後我們進行編輯操作,點擊列表中的Edit按鈕,跳轉到編輯頁面: 雖然頁面中显示的是Add,但確實是Edit頁面。我們編輯以後點擊Save按鈕,然後返回列表頁即可看到編輯后的內容。 在列表頁中,如果我們點擊Delete按鈕,則會刪除改條目。 到...

Colder框架硬核更新(Sharding+IOC)

目錄 引言 控制反轉 讀寫分離分庫分表 理論基礎 設計目標 現狀調研 設計思路 實現之過五關斬六將 動態對象 動態模型緩存 數據源移植 查詢表達式樹深度移植 數據合併算法 事務支持 實際使用 展望未來 引言 前方硬核警告:全文乾貨11000+字,請耐心閱讀 遙想去年這個時候,差不多剛剛畢業,如今正式工作差不多一年了。Colder開源快速開發框架從上次版本發布至今差不多有三個月了,Github的星星5個版本框架總共也有近800顆,QQ群從最初的一個人發展到現在的500人(吐槽下,人數上限了,太窮開不起SVIP,所以另開了一個,群號在文章末),這都是大家共同發展的結果,本框架能夠幫助到大家鄙人就十分開心。但是,技術是不斷髮展的,本框架也必須適應潮流,不斷升級才能夠與時俱進,在實際意義上提高生產力。本系列框架從原始雛形(鄙人畢業設計)=>.NET45+Easyui=>.NET Core2.1+Easyui=>.NET45+AdminLTE=>.NET Core2.1+AdminLTE,這其中都是根據實際情況不斷升級。例如鄙人最初的畢業設計搭建了框架的雛形(倉儲層不夠完善、界面較簡陋),並不適合實際的生產開發,因此使用Easyui作為前端UI框架(控件豐富,使用簡單),后又由於.NET Core的發展迅速,已經發展到2.0,其基礎類庫組件也相對比較成熟了,因此從.NET45遷移到.NET Core。後來發現Easyui的樣式比較落後,給人一種過時古老的感覺,故而又將前端UI改為基於Bootstrap的AdminLTE,比較成熟主流並且開源。 但是,新的要求又出現了: 由於沒有使用IOC導致各個類通過New導致的強耦合問題 數據庫大數據量如何處理的問題 因此,本次版本更新主要就是為了解決上述的問題,即全面使用Autofac作為IOC容器實現解耦以及數據庫讀寫分離分庫分表( Sharding )支持。下面將分別介紹。 這次更新.NET45版本與.NET Core版本同步更新: .NE...

Java基礎(六) static五大應用場景

static和final是兩個我們必須掌握的關鍵字。不同於其他關鍵字,他們都有多種用法,而且在一定環境下使用,可以提高程序的運行性能,優化程序的結構。上一個章節我們講了final關鍵字的原理及用法,本章節我們來了解一下static關鍵字原理及其用法。 一. static特點 static是一個修飾符,通常用於修飾變量和方法,如開發過程中用到的字典類數據都會用到static來修飾,工具類方法,如Dateutils,Stringutils這類工具方法也會用到static來修飾,那麼除了這兩種最常用的場景外,是否還有其他場景呢,答案是:有的,總共五種: static變量 static方法 static代碼塊 static內部類 static包內導入 static修飾的變量、方法、代碼塊、內部類在類加載期間就已經完成初始化,存儲在Java Heap(JDK7.0之前存儲在方法區)中靜態存儲區,因此static優於對象而存在。 static修飾的成員(變量、方法)被所有對象所共享,也叫靜態變量或靜態方法,可直接通過類調用(也建議通過類調用)。 二. static 變量 static變量隨着類的加載而存在,隨着類的消失而消失,當類被加載時,就會為靜態變量在Java Heap中分配內存空間,可以通過【類.變量名】和【對象.變量名】的方式調用,建議直接使用【類.變量名】的方式, public class Person { private String name; private static int eyeNum; public static int legNum = 2; public String getName() { return name; } public void setName(String name) { this.name = name; } public static int getEyeNum() { return eyeNum; } public static void setEyeNum(int eyeNum) { ...