並發問題:大資料量的訪問,並發資料量訪問

來源:互聯網
上載者:User

並發問題:大資料量的訪問,並發資料量訪問

今天突然關注到這個問題,從網上看了很多,受益良多。記錄下來,以後回顧~


之前在工作中就遇到過這種情況,兩個使用者同時操作一條記錄,A使用者查詢某條記錄,B使用者把這條記錄刪除,A使用者將查詢的某條記錄的某些值儲存到其他的表裡。這個bug也是困擾了好久,因為A使用者的這個方法特別複雜,執行的時間比較長,所以這個問題出現的機率還很高的呢。後來的解決方案是,A使用者在最後儲存前,再查一下這條記錄。是從代碼邏輯方面解決的這個問題,確實好了很多,但始終覺得是治標不治本。今天看完以後覺得有更好的解決方案的呢。


part1:

大並發大資料量請求一般會分為幾種情況:

1.大量的使用者同時對系統的不同功能頁面進行尋找,更新操作

2.大量的使用者同時對系統的同一個頁面,同一個表的大資料量進行查詢操作

3.大量的使用者同時對系統的同一個頁面,同一個表進行更新操作

 

對於第一種情況一般處理方法如下:

一。對伺服器層面的處理

1. 調整IIS 7應用程式集區隊列長度

由原來的預設1000改為65535。

IIS Manager > ApplicationPools > Advanced Settings

Queue Length : 65535

2.  調整IIS 7的appConcurrentRequestLimit設定

由原來的預設5000改為100000。

c:\windows\system32\inetsrv\appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000

在%systemroot%\System32\inetsrv\config\applicationHost.config中可以查看到該設定:

[html] view plaincopy
  1. <serverRuntime appConcurrentRequestLimit="100000" />   

3. 調整machine.config中的processModel>requestQueueLimit的設定

由原來的預設5000改為100000。

[html] view plaincopy
  1. <configuration>  
  2.     <system.web>  
  3.         <processModel requestQueueLimit="100000"/>   

4. 修改註冊表,調整IIS 7支援的同時TCPIP串連數

由原來的預設5000改為100000。

reg add HKLM\System\CurrentControlSet\Services\HTTP\Parameteris /v MaxConnections /t REG_DWORD /d 100000 

完成上述4個設定,就基本可以支援10萬個同時請求。如果訪問量達到10萬以上,就可以考慮將程式和資料庫按功能模組劃分部署到多個伺服器分擔訪問壓力。另外可以考慮軟硬體負載平衡。硬體負載平衡能夠直接通過智能交換器實現,處理能力強,而且與系統無關,但是價格貴,配置困難,不能區分實習系統與應狀態。所以硬體負載平衡適用於一大堆裝置,大訪問量,簡單應用。軟體負載平衡是基於系統與應用的,能過更好地根據系統與應用的狀況來分配負載。性價比高。PCL負載平衡軟體,Linux下的LVS軟體。

 

二。對資料庫層面的處理

      當兩個使用者同時訪問一個頁面,一個使用者可能更新的是另一個使用者已經刪除的記錄。或者,在一個使用者載入頁面跟他點擊刪除按鈕之間的時間裡,另一個使用者修改了這條記錄的內容。所以需要考慮資料庫鎖的問題

有下面三中並發控制策略可供選擇:

Ø 什麼都不做 –如果並發使用者修改的是同一條記錄,讓最後提交的結果生效(預設的行為)

Ø 開放式並發(Optimistic Concurrency) - 假定並發衝突只是偶爾發生,絕大多數的時候並不會出現; 那麼,當發生一個衝突時,僅僅簡單的告知使用者,他所作的更改不能儲存,因為別的使用者已經修改了同一條記錄

Ø 保守式並發(Pessimistic Concurrency) – 假定並發衝突經常發生,並且使用者不能容忍被告知自己的修改不能儲存是由於別人的並發行為;那麼,當一個使用者開始編輯一條記錄,鎖定該記錄,從而防止其他使用者編輯或刪除該記錄,直到他完成並提交自己的更改

當多個使用者試圖同時修改資料時,需要建立控制機制來防止一個使用者的修改對同時操作的其他使用者所作的修改產生不利的影響。處理這種情況的系統叫做“並發控制”。

並發控制的類型

通常,管理資料庫中的並發有三種常見的方法:

  • 保守式並發控制 - 在從擷取記錄直到記錄在資料庫中更新的這段時間內,該行對使用者不可用。
  • 開放式並發控制 - 只有當實際更新資料時,該行才對其他使用者不可用。更新將在資料庫中檢查該行並確定是否進行了任何更改。如果試圖更新已更改的記錄,則將導致並發衝突。
  • 最後的更新生效 - 只有當實際更新資料時,該行才對其他使用者不可用。但是,不會將更新與初始記錄進行比較;而只是寫出記錄,這可能就改寫了自上次重新整理記錄後其他使用者所進行的更改。
保守式並發

保守式並發通常用於兩個目的。第一,在某些情況下,存在對相同記錄的大量爭用。在資料上放置鎖所費的成本小於發生並發衝突時復原更改所費的成本。

在事務過程中不宜更改記錄的情況下,保守式並發也非常有用。庫存應用程式便是一個很好的樣本。假定有一個公司代表正在為一名潛在的客戶檢查庫存。您通常要鎖定記錄,直到產生訂單為止,這通常會將該項標記為“已訂購”狀態並將其從可用庫存中移除。如果未產生訂單,則將釋放該鎖,以便其他檢查庫存的使用者得到準確的可用庫存計數。

但是,在斷開的結構中無法進行保守式並發控制。串連開啟的時間只夠讀取資料或更新資料,因此不能長時間地保持鎖。此外,長時間保留鎖的應用程式將無法進行伸縮。

開放式並發

在開放式並發中,只有在訪問資料庫時才設定並保持鎖。這些鎖將防止其他使用者在同一時間更新記錄。除了進行更新這一確切的時刻之外,資料始終可用。有關更多資訊,請參見開放式並發。

當試圖更新時,已更改行的初始版本將與資料庫中的現有行進行比較。如果兩者不同,更新將失敗,並引發並發錯誤。這時,將由您使用所建立的商務邏輯來協調這兩行。

最後的更新生效

當使用“最後的更新生效”時,不會對初始資料進行檢查,而只是將更新寫入資料庫。很明顯,可能會發生以下情況:

  • 使用者 A 從資料庫擷取一項記錄。
  • 使用者 B 從資料庫擷取相同的記錄,對其進行修改,然後將更新後的記錄寫回資料庫。
  • 使用者 A 修改“舊”記錄並將其寫回資料庫。

在上述情況中,使用者 A 永遠也不會看到使用者 B 作出的更改。如果您計劃使用並發控制的“最後的更新生效”方法,則要確保這種情況是可以接受的。

ADO.NET 和 Visual Studio .NET 中的並發控制

因為資料結構基於斷開的資料,所以 ADO.NET 和 Visual Studio .NET 使用開放式並發。因此,您需要添加商務邏輯,以利用開放式並發解決問題。

如果您選擇使用開放式並發,則可以通過兩種常規的方法來確定是否已發生更改:版本方法(實際版本號碼或日期時間戳記)和儲存所有值方法。

版本號碼方法

在版本號碼方法中,要更新的記錄必須具有一個包含日期時間戳記或版本號碼的列。當讀取該記錄時,日期時間戳記或版本號碼將儲存在用戶端。然後,將對該值進行部分更新。

處理並發的一種方法是僅當 WHERE 子句中的值與記錄上的值匹配時才進行更新。該方法的 SQL 表示形式為:

UPDATE Table1 SET Column1 = @newvalue1, Column2 = @newvalue2WHERE DateTimeStamp = @origDateTimeStamp

或者,可以使用版本號碼進行比較:

UPDATE Table1 SET Column1 = @newvalue1, Column2 = @newvalue2WHERE RowVersion = @origRowVersionValue

如果日期時間戳記或版本號碼匹配,則表明資料存放區區中的記錄未被更改,並且可以安全地使用資料集中的新值對該記錄進行更新。如果不匹配,則將返回錯誤。您可以編寫代碼,在 Visual Studio .NET 中實現這種形式的並發檢查。您還必須編寫代碼來響應任何更新衝突。為了確保日期時間戳記或版本號碼的準確性,您需要在表上設定觸發器,以便在發生對行的更改時,對日期時間戳記或版本號碼進行更新。

儲存所有值方法

使用日期時間戳記或版本號碼的替代方法是在讀取記錄時擷取所有欄位的副本。ADO.NET 中的 DataSet 對象維護每個修改記錄的兩個版本:初始版本(最初從資料來源中讀取的版本)和修改版本(表示使用者更新)。當試圖將記錄寫回資料來源時,資料行中的初始值將與資料來源中的記錄進行比較。如果它們匹配,則表明資料庫記錄在被讀取後尚未經過更改。在這種情況下,資料集中已更改的值將成功地寫入資料庫。

對於資料配接器的四個命令(DELETE、INSERT、SELECT 和 UPDATE)來說,每個命令都有一個參數集合。每個命令都有用於初始值和當前值(或修改值)的參數。

 

 

對於第二種情況的處理:

因為是大並發請求,也能採用第一種情況的處理方法,另外因為是對大資料量進行檢索,所以需要考慮查詢效率的問題

1.對錶按查詢條件建立索引

2.對查詢語句進行最佳化

3.可以考慮對查詢資料使用緩衝

 

對於第三種情況的處理:

也能採用第一種情況的處理方法,另外因為是對同一個表進行更新操作,可以考慮使用下面的處理方法:

1.先將資料儲存到緩衝中,當資料達到一定的數量後,再更新到資料庫中

2.將表按索引劃分(分表,分區),如:對於一個儲存全國人民資訊的表,這個資料量是很大的,如果按省劃分為多個表,在將全國的人民資訊按省儲存到相應的表中,然後根據省份對相應的並進行查詢和更新,這樣大並發和大資料量的問題就會減小很多


part2:


如何處理大量資料並行作業 檔案快取,資料庫緩衝,最佳化sql,資料分流,資料庫表的橫向和縱向劃分,最佳化代碼結構! 鎖述的概一. 為什麼要引入鎖多個使用者同時對資料庫的並行作業時會帶來以下資料不一致的問題: 丟失更新A,B兩個使用者讀同一資料並進行修改,其中一個使用者的修改結果破壞了另一個修改的結果,比如訂票系統 髒讀A使用者修改了資料,隨後B使用者又讀出該資料,但A使用者因為某些原因取消了對資料的修改,資料恢複原值,此時B得到的資料就與資料庫內的資料產生了不一致 不可重複讀取A使用者讀取資料,隨後B使用者讀出該資料並修改,此時A使用者再讀取資料時發現前後兩次的值不一致 並發控制的主要方法是封鎖,鎖就是在一段時間內禁止使用者做某些操作以避免產生資料不一致 二 鎖的分類鎖的類別有兩種分法:1. 從資料庫系統的角度來看:分為獨佔鎖(即排它鎖),共用鎖定和更新鎖定MS-SQL Server 使用以下資源鎖模式。鎖模式 描述共用 (S) 用於不更改或不更新資料的操作(唯讀操作),如 SELECT 語句。更新 (U) 用於可更新的資源中。防止當多個會話在讀取、鎖定以及隨後可能進行的資源更新時發生常見形式的死結。排它 (X) 用於資料修改操作,例如 INSERT、UPDATE 或 DELETE。確保不會同時同一資源進行多重更新。意圖鎖定 用於建立鎖的階層。意圖鎖定的類型為:意圖共用 (IS)、意向排它 (IX) 以及與意向排它共用 (SIX)。架構鎖 在執行依賴於表架構的操作時使用。架構鎖的類型為:架構修改 (Sch-M) 和架構穩定性 (Sch-S)。大容量更新 (BU) 向表中大量複製資料並指定了 TABLOCK 提示時使用。 共用鎖定共用 (S) 鎖允許並發事務讀取 (SELECT) 一個資源。資源上存在共用 (S) 鎖時,任何其它事務都不能修改資料。一旦已經讀取資料,便立即釋放資源上的共用 (S) 鎖,除非將交易隔離等級設定為可重複讀或更進階別,或者在事務生存周期內用鎖定提示保留共用 (S) 鎖。 更新鎖定更新 (U) 鎖可以防止通常形式的死結。一般更新模式由一個事務組成,此事務讀取記錄,擷取資源(頁或行)的共用 (S) 鎖,然後修改行,此操作要求鎖轉換為排它 (X) 鎖。如果兩個事務獲得了資源上的共用模式鎖,然後試圖同時更新資料,則一個事務嘗試將鎖轉換為排它 (X) 鎖。共用模式到排它鎖的轉換必須等待一段時間,因為一個事務的排它鎖與其它事務的共用模式鎖不相容;發生鎖等待。第二個事務試圖擷取排它 (X) 鎖以進行更新。由於兩個事務都要轉換為排它 (X) 鎖,並且每個事務都等待另一個事務釋放共用模式鎖,因此發生死結。 若要避免這種潛在的死結問題,請使用更新 (U) 鎖。一次只有一個事務可以獲得資源的更新 (U) 鎖。如果事務修改資源,則更新 (U) 鎖轉換為排它 (X) 鎖。否則,鎖轉換為共用鎖定。 排它鎖排它 (X) 鎖可以防止並發事務對資源進行訪問。其它事務不能讀取或修改排它 (X) 鎖鎖定的資料。 意圖鎖定意圖鎖定表示 SQL Server 需要在階層中的某些底層資源上擷取共用 (S) 鎖或排它 (X) 鎖。例如,放置在表級的共用意圖鎖定表示事務打算在表中的頁或行上放置共用 (S) 鎖。在表級設定意圖鎖定可防止另一個事務隨後在包含那一頁的表上擷取排它 (X) 鎖。意圖鎖定可以提高效能,因為 SQL Server 僅在表級檢查意圖鎖定來確定事務是否可以安全地擷取該表上的鎖。而無須檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表。 意圖鎖定包括意圖共用 (IS)、意向排它 (IX) 以及與意向排它共用 (SIX)。 鎖模式 描述意圖共用 (IS) 通過在各資源上放置 S 鎖,表明事務的意向是讀取階層中的部分(而不是全部)底層資源。意向排它 (IX) 通過在各資源上放置 X 鎖,表明事務的意向是修改階層中的部分(而不是全部)底層資源。IX 是 IS 的超集。與意向排它共用 (SIX) 通過在各資源上放置 IX 鎖,表明事務的意向是讀取階層中的全部底層資源並修改部分(而不是全部)底層資源。允許頂層資源上的並發 IS 鎖。例如,表的 SIX 鎖在表上放置一個 SIX 鎖(允許並發 IS 鎖),在當前所修改頁上放置 IX 鎖(在已修改行上放置 X 鎖)。雖然每個資源在一段時間內只能有一個 SIX 鎖,以防止其它事務對資源進行更新,但是其它事務可以通過擷取表級的 IS 鎖來讀取階層中的底層資源。 獨佔鎖:只允許進行鎖定操作的程式使用,其他任何對他的操作均不會被接受。執行資料更新命令時,SQL Server會自動使用獨佔鎖。當對象上有其他鎖存在時,無法對其加獨佔鎖。共用鎖定:共用鎖定鎖定資源可以被其他使用者讀取,但其他使用者無法修改它,在執行Select時,SQL Server會對對象加共用鎖定。更新鎖定:當SQL Server準備更新資料時,它首先對資料對象作更新鎖定鎖定,這樣資料將不能被修改,但可以讀取。等到SQL Server確定要進行更新資料操作時,他會自動將更新鎖定換為獨佔鎖,當對象上有其他鎖存在時,無法對其加更新鎖定。 2. 從程式員的角度看:分為樂觀鎖和悲觀鎖。樂觀鎖:完全依靠資料庫來管理鎖的工作。悲觀鎖:程式員自己管理資料或對象上的鎖處理。 MS-SQLSERVER 使用鎖在多個同時在資料庫內執行修改的使用者間實現封閉式並行存取控制 三 鎖的粒度鎖粒度是被封鎖目標的大小,封鎖粒度小則並發性高,但開銷大,封鎖粒度大則並發性低但開銷小 SQL Server支援的鎖粒度可以分為為行、頁、鍵、鍵範圍、索引、表或資料庫擷取鎖 資源 描述RID 行標識符。用於單獨鎖定表中的一行。鍵 索引中的行鎖。用於保護可串列事務中的鍵範圍。頁 8 KB (KB) 的資料頁或索引頁。擴充盤區 相鄰的八個資料頁或索引頁構成的一組。表 包括所有資料和索引在內的整個表。DB 資料庫。 四 鎖定時間的長短 鎖保持的時間長度為保護所請求層級上的資源所需的時間長度。 用於保護讀取操作的共用鎖定的保持時間取決於交易隔離等級。採用 READ COMMITTED 的預設交易隔離等級時,只在讀取頁的期間內控制共用鎖定。在掃描中,直到在掃描內的下一頁上擷取鎖時才釋放鎖。如果指定 HOLDLOCK 提示或者將交易隔離等級設定為 REPEATABLE READ 或 SERIALIZABLE,則直到事務結束才釋放鎖。 根據為遊標設定的並發選項,遊標可以擷取共用模式的滾動鎖以保護提取。當需要滾動鎖時,直到下一次提取或關閉遊標(以先發生者為準)時才釋放滾動鎖。但是,如果指定 HOLDLOCK,則直到事務結束才釋放滾動鎖。 用於保護更新的排它鎖將直到事務結束才釋放。如果一個串連試圖擷取一個鎖,而該鎖與另一個串連所控制的鎖衝突,則試圖擷取鎖的串連將一直阻塞到: 將衝突鎖釋放而且串連擷取了所請求的鎖。 串連的逾時間隔已到期。預設情況下沒有逾時間隔,但是一些應用程式設定逾時間隔以防止無限期等待 五 SQL Server 中鎖的自訂 1 處理死結和設定死結優先順序 死結就是多個使用者申請不同封鎖,由於申請者均擁有一部分封鎖權而又等待其他使用者擁有的部分封鎖而引起的無休止的等待 可以使用SET DEADLOCK_PRIORITY控制在發生死結情況時會話的反應方式。如果兩個進程都鎖定資料,並且直到其它進程釋放自己的鎖時,每個進程才能釋放自己的鎖,即發生死結情況。 2 處理逾時和設定鎖逾時期間。 @@LOCK_TIMEOUT 返回當前會話的當前鎖逾時設定,單位為毫秒 SET LOCK_TIMEOUT 設定允許應用程式設定語句等待阻塞資源的最長時間。當語句等待的時間大於 LOCK_TIMEOUT 設定時,系統將自動取消阻塞的語句,並給應用程式返回”已超過了鎖請求逾時時段”的 1222 號錯誤資訊 樣本下例將鎖逾時期限設定為 1,800 毫秒。SET LOCK_TIMEOUT 1800 3) 設定交易隔離等級。 4 ) 對 SELECT、INSERT、UPDATE 和 DELETE 語句使用表級鎖定提示。 5) 配置索引的鎖定粒度可以使用 sp_indexoption 系統預存程序來設定用於索引的鎖定粒度 六 查看鎖的資訊 1 執行 EXEC SP_LOCK 報告有關鎖的資訊2 查詢分析器中按Ctrl+2可以看到鎖的資訊 七 使用注意事項 如何避免死結1 使用事務時,盡量縮短事務的邏輯處理過程,及早提交或復原事務;2 設定死結逾時參數為合理範圍,如:3分鐘-10分種;超過時間,自動放棄本次操作,避免進程懸掛;3 最佳化程式,檢查並避免死結現象出現;4 .對所有的指令碼和SP都要仔細測試,在正是版本之前。5 所有的SP都要有錯誤處理(通過@error)6 一般不要修改SQL SERVER事務的預設層級。不推薦強行加鎖 解決問題 如何對行 表 資料庫加鎖 八 幾個有關鎖的問題 ?
1234567891011121314151617 1 如何鎖一個表的某一行 SETTRANSACTION ISOLATION LEVEL READ UNCOMMITTED SELECT* FROMtable ROWLOCK WHEREid = 1 2 鎖定資料庫的一個表 SELECT* FROMtable WITH (HOLDLOCK) 加鎖語句:sybase:updatesetcol1=col1 where1=0 ;MSSQL:selectcol1 from表 (tablockx) where1=0 ;oracle:LOCKTABLEINEXCLUSIVE MODE ;

 

加鎖後其它人不可操作,直到加鎖使用者解鎖,用commit或rollback解鎖 幾個例子協助大家加深印象設table1(A,B,C)A B Ca1 b1 c1a2 b2 c2a3 b3 c3 1)排它鎖建立兩個串連?
123456789101112 在第一個串連中執行以下語句begintranupdatetable1setA=’aa’whereB=’b2′waitfor delay ’00:00:30′ –等待30秒committran在第二個串連中執行以下語句begintranselect* fromtable1whereB=’b2′committran

 

 若同時執行上述兩個語句,則select查詢必須等待update執行完畢才能執行即要等待30秒 2)共用鎖定?
123456789101112131415 在第一個串連中執行以下語句begintranselect* fromtable1 holdlock -holdlock人為加鎖whereB=’b2′waitfor delay ’00:00:30′ –等待30秒committran 在第二個串連中執行以下語句begintranselectA,C fromtable1whereB=’b2′updatetable1setA=’aa’whereB=’b2′committran

 

 若同時執行上述兩個語句,則第二個串連中的select查詢可以執行而update必須等待第一個事務釋放共用鎖定轉為排它鎖後才能執行 即要等待30秒 3)死結?
12345678910111213141516171819202122232425 增設table2(D,E)D Ed1 e1d2 e2在第一個串連中執行以下語句begintranupdatetable1setA=’aa’whereB=’b2′waitfor delay ’00:00:30′updatetable2setD=’d5′whereE=’e1′committran 在第二個串連中執行以下語句begintranupdatetable2setD=’d5′whereE=’e1′waitfor delay ’00:00:10′updatetable1setA=’aa’whereB=’b2′committran

 

 同時執行,系統會檢測出死結,並中止進程 補充一點:Sql Server2000支援的表級鎖定提示 HOLDLOCK 持有共用鎖定,直到整個事務完成,應該在被鎖對象不需要時立即釋放,等於SERIALIZABLE交易隔離等級 NOLOCK 語句執行時不發出共用鎖定,允許髒讀 ,等於 READ UNCOMMITTED交易隔離等級 PAGLOCK 在使用一個表鎖的地方用多個頁鎖 READPAST 讓sql server跳過任何鎖定行,執行事務,適用於READ UNCOMMITTED交易隔離等級只跳過RID鎖,不跳過頁,地區和表鎖 ROWLOCK 強制使用行鎖 TABLOCKX 強制使用獨佔表級鎖,這個鎖在事務期間阻止任何其他事務使用這個表







JAVA高並發問題,大資料,頻繁I/O操作

建議採用緩衝處理,按照你說的這種資料量,基於redis的緩衝完全可以滿足,存取速度可以10W+的,另外,擬採用的hashMap 是ConcurrentHashMap還是其他,頁面展示是增量查詢還是直接所有的再查詢一次,socket資料接收你是用的netty還是mina,這都需要經過仔細的斟酌考慮設計的。有這麼大的並發的需求,完全可以考慮做分布式叢集的,估計這隻是領導想要的目標吧
 
學習大資料量,高並發處理應該看什書?

先學測試吧。不是那種業務功能的測試,是系統的測試。因為要解決大資料量、高並發的問題,我個人的知識與經驗是:1、先用單機測試。用工具產生大並發量去轟擊伺服器,直至伺服器緩慢,甚至接近崩潰;3、找到系統瓶頸後,最佳化,解決這個瓶頸,然後再迴圈測試。這時你又會發現新的瓶頸,再解決。迴圈1 - 3步,直到各方面基本平衡為止。4、當單機無法解決問題的時候,接著開始考慮負載平衡,考慮分布式方案,然後再用 1 - 3 的步驟分析與測試。
 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.