1. 程式人生 > >高併發處理系統的理解---資料一致性(還有一點問題)

高併發處理系統的理解---資料一致性(還有一點問題)

  • 伺服器配置
  • 資料庫設計以及優化
  • 快取
  • 資料一致性處理

 伺服器配置:

         叢集的環境,每個主機選擇apahe 還是nginx,nignx的併發性好。nginx和apche區別 以及伺服器的配置,例如快取大小等

        根據實際情況,可能對於影象比較多的情況,單獨配置nginx伺服器,作為影象伺服器。在實習中使用的是七牛家的雲端儲存單獨作為圖片儲存,將有關車輛的上傳圖片全部放在上面。

資料庫設計以及優化

       (1)表的設計:

           儲存引擎:innodb還是 myisam? innodb支援事務外來鍵,可以在崩潰時恢復(事務中redo日誌實現),myisam不支援;存放資料的方式不同:myisam將表的結構frm 資料myd索引myi存在資料庫目標中;innodb只在資料庫目標檔案中存在表的結構;索引採用B+樹,myisam索引葉結點儲存的是指標,指向資料,innodb存的就是資料;myisam佔用空間小,在讀的業務比較多的情況下采用myisam比較好。

         欄位的設定: 儘量使用短的欄位,提高效率,建立索引也能減少資源浪費; 整型型別,比字元型別比較快;varchar 和 char不定長(節約空間)和定長(查詢快)選用;索引欄位:該欄位進行不同的比較多,欄位值不易過長。

         合理選擇資料的冗餘:可以根據實際情況,不滿足三正規化:設定冗餘欄位,可以減少客戶的處理,滿足三正規化,表之間的關係比較清晰,但是因為有外來鍵什麼的,多表關聯可能效能降低,加大了使用者的程式設計難度。

      (2)分庫分表

        針對大表,可以根據實際情況垂直分表或者水平分表。

      垂直分表:對於大表中的某些欄位經常使用,可以分表;

      水平分表:例如月份,將不同的月份的資料存在不同的表中。

    (3)mysql叢集的環境

       讀寫分離:主要針對讀操作比較多的情況下

        目的:給大型網站緩解查詢壓力

        原理:伺服器執行amobe服務,可以判斷sql是寫還是讀操作。收到sql語句是寫,伺服器將寫送到master mysql處理,利用mysql proxy機制然後同步到slave mysql;

         當伺服器是select時,伺服器會根據負載均衡挑選出一個slave mysql,將select語句送到並處理。

快取:

       可以將一些不動的頁面:頁面靜態化/部分頁面靜態化;

        或者將一些資料存在memcache或者redis中,不用去查表

資料一致性處理

      當多個程序同時操作同一個資料,會產生資源爭搶,資料一致性的問題。

       高併發情況下,涉及到寫操作時,不可能直接操作資料庫,大併發的連線會導致mysql請求會阻塞,比如大量的insert update 請求到,會直接導致無數的行鎖和表鎖,甚至最後堆積很多,從來觸發too many connections 錯誤。

     web伺服器 nginx和apache連線的程序有限,cpu上下文程序切換也會增加額外的開銷,所以響應一定快。

      這時可以採用

     高併發下的資料安全,防超發,以搶票系統為例:

    (1)訊息佇列:

        將票數資源存在redis中,將請求存入訊息佇列(redis下的list阻塞的,可以實現訊息佇列,還可以實現優先訊息佇列點選開啟連結)中,依次處理。缺點 :這樣會處理比較慢,等待時間比較長。

    

:對於讀操作是否也進入佇列,這個問題根據具體的場景,像12306應該是不在佇列中或者是優先排在最前面的,因為只是讀,要求塊。 

(2)加鎖

      常見的鎖:        排它鎖;樂觀鎖;悲觀鎖;

      排他鎖:在進行寫時,禁止一切的讀和寫;

      樂觀鎖:認為在寫的時候,別人不在寫,維護一個version號,等處理後對照version好,一致則對,否則回滾,操作不成功,

      悲觀鎖:認為在寫的時候,別人也在寫。採用資料庫提供的鎖機制:在寫操作的時(insert updata 等)myisam預設是鎖表,innodb根據是否是主鍵,主鍵則行鎖,否則表鎖。讀操作,innodb採用mvcc版本控制。

     可以採用樂觀鎖+回滾:

       

    採用悲觀鎖: