memcached緩存mysql
Ⅰ mysql有基於LRU緩沖池,其它輔助緩存如memcached和redis的意義應該就不需要了,還是有其它需要的理由
1、首先明確是不是一定要上緩存,當前架構的瓶頸在哪裡,若瓶頸真是資料庫操作上,再繼續往下看。
2、明確memcached和redis的區別,到底要使用哪個。前者終究是個緩存,不可能永久保存數據(LRU機制),支持分布式,後者除了緩存的同時也支持把數據持久化到磁碟等,redis要自己去實現分布式緩存(貌似最新版本的已集成),自己去實現一致性hash。因為不知道應用場景,不好說一定要用memcache還是redis,說不定用mongodb會更好,比如在存儲日誌方面。
3、緩存量大但又不常變化的數據,比如評論。
4、思路是對的,清晰明了,讀DB前,先讀緩存,如果有直接返回,如果沒有再讀DB,然後寫入緩存層並返回。
5、考慮是否需要主從,讀寫分離,考慮是否分布式部署,考慮是否後續水平伸縮。
6、想要一勞永逸,後續維護和擴展方便,那就將現有的代碼架構優化,按你說的替換資料庫組件需要改動大量代碼,說明當前架構存在問題。可以利用現有的一些框架,比如SpringMVC,將應用層和業務層和資料庫層解耦。再上緩存之前把這些做好。
7、把讀取緩存等操作做成服務組件,對業務層提供服務,業務層對應用層提供服務。
8、保留原始資料庫組件,優化成服務組件,方便後續業務層靈活調用緩存或者是資料庫。
9、不建議一次性全量上緩存,最開始不動核心業務,可以將邊緣業務先換成緩存組件,一步步換至核心業務。
10、刷新內存,以memcached為例,新增,修改和刪除操作,一般採用lazy load的策略,即新增時只寫入資料庫,並不會馬上更新Memcached,而是等到再次讀取時才會載入到Memcached中,修改和刪除操作也是更新 資料庫,然後將Memcached中的數據標記為失效,等待下次讀取時再載入。
大方向兩種方案:
1、腳本同步:自己寫腳本將資料庫數據寫入到redis/memcached。這就涉及到實時數據變更的問題(mysql row binlog的實時分析),binlog增量訂閱Alibaba 的canal ,以及緩存層數據 丟失/失效 後的數據同步恢復問題。
2、業務層實現:先讀取nosql緩存層,沒有數據再讀取mysql層,並寫入數據到nosql。nosql層做好多節點分布式(一致性hash),以及節點失效後替代方案(多層hash尋找相鄰替代節點),和數據震盪恢復了。
Ⅱ 解決MYSQL查詢瓶頸問題提升讀取效率無鎖查詢技巧mysql不加鎖查詢
在大規模數據存儲和處理中,MYSQL資料庫是一個非常常用和有力的工具。但是,在查詢數據的過程中,可能會出現瓶頸和效率低下的問題,特別是在高並發讀取的場景中。針對這種問題,我們可以採用無鎖查詢技巧,從而大幅提升讀取效率。
一、什麼是無鎖查詢
傳統資料庫在並發讀取數據時,會發生鎖定的情況。例如,在一條記錄被第一個請求查詢時,此時其他請求將無法讀取該記錄,只能等待。這種方式本身是合理的,可以避免數據沖突和不一致性,但是在高並發場景下,會導致性能瓶頸和資源佔用。
而無鎖查詢,則是一種基於CAS(Compare and Swap)操作的原子性操作,它使得多個線程可以同時讀取同一條記錄,而不會造成數據不一致。
二、如何實現無鎖查詢技巧
1.使用load data local infile代替insert into
在MYSQL中,我們可以使用load data local infile語句將數據一次性導入到資料庫中,從而避免了大量的寫入操作。這個操作方式不僅可以提高寫入效率,還避免了數據沖突。
2.使用memcached或redis緩存查詢結果
在高並發讀取時,我們可以將查詢的結果緩存到memcached或redis中,從而避免多次查詢同一記錄的問題。這種方式可以大幅提高查詢效率,減少資料庫的壓力。
3.使用第三方插件進行無鎖操作
一些第三方插件,例如MyISAM存儲引擎以及Apache Cassandra等,都提供了一些無鎖查詢操作。我們可以根據具體的需求選擇一個最適合的插件,來提高查詢效率和性能。
三、案例分析:使用無鎖查詢技巧提升MYSQL讀取效率
下面給出一個實際的案例,演示如何通過無鎖查詢技巧來提高MYSQL的讀取效率。
假設我們有一個用戶表user,其中包含以下欄位:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`age` int(11) NOT NULL,
`gender` varchar(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
我們希望查詢所有年齡大於20歲的男性用戶,並將結果緩存到memcached中。
使用普通查詢方式的代碼如下:
$mysqli = new mysqli(“localhost”, “username”, “password”, “test”);
if ($mysqli->connect_errno) {
die(“Fled to connect to MySQL: (” . $mysqli->connect_errno . “) ” . $mysqli->connect_error);
}
$query=”SELECT * FROM user WHERE age>20 AND gender=’male'”;
$result=mysqli_query($mysqli,$query);
while($row=mysqli_fetch_assoc($result)){
//do something with the result
}
mysqli_close($mysqli);
使用無鎖查詢技巧的代碼如下:
$mysqli = new mysqli(“localhost”, “username”, “password”, “test”);
if ($mysqli->connect_errno) {
die(“Fled to connect to MySQL: (” . $mysqli->connect_errno . “) ” . $mysqli->connect_error);
}
$memcache = new Memcache;
$memcache->connect(‘localhost’, 11211) or die (“Could not connect”);
$query=”SELECT * FROM user WHERE age>20 AND gender=’male'”;
$cache_key=md5($query);
if($cache_result=$memcache->get($cache_key)){
while($row=mysqli_fetch_assoc($cache_result)){
//do something with the result
}
}else{
$result=mysqli_query($mysqli,$query);
while($row=mysqli_fetch_assoc($result)){
$cache_result[]=$row;
//do something with the result
}
$memcache->set($cache_key,$cache_result,0,1200);
}
mysqli_close($mysqli);
如上代碼可以看出,我們先使用memcached進行查詢結果的緩存,然後再從緩存中讀取數據。這樣就避免了多次查詢同一記錄的問題,大幅提高了讀取效率和性能。
四、總結
無鎖查詢技巧是一種提高MYSQL讀取效率和性能的有效方法,在高並發讀取場景下尤其適用。我們可以通過幾種方法來實現無鎖查詢,例如使用load data local infile代替insert into、使用memcached或redis緩存查詢結果、使用第三方插件進行無鎖操作等。在實際應用中,我們應該根據具體的需求來選擇合適的方法,以達到最佳的效果。