當前位置:首頁 » 硬碟大全 » 緩存的讀寫分離
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

緩存的讀寫分離

發布時間: 2022-05-12 04:07:40

㈠ redis需要讀寫分離嗎

首先說結論:這個要跟你具體的架構實現以及業務相關,常見的應用場景下我覺得redis沒必要進行讀寫分離。


先來討論一下為什麼要讀寫分離:

讀寫分離使用於大量讀請求的情況,通過多個slave分攤了讀的壓力,從而增加了讀的性能。

過多的select會阻塞住資料庫,使你增刪改不能執行,而且到並發量過大時,資料庫會拒絕服務。

因而通過讀寫分離,從而增加性能,避免拒絕服務的發生。

我認為需要讀寫分離的應用場景是:寫請求在可接受范圍內,但讀請求要遠大於寫請求的場景。


再來討論一下redis常見的應用場景:

  1. 緩存

  2. 2. 排名型的應用,訪問計數型應用

  3. 3. 實時消息系統

首先說一下緩存集群,這也是非常常見的應用場景:

  1. 緩存主要解決的是用戶訪問時,怎麼以更快的速度得到數據。

  2. 2. 單機的內存資源是很有限的,所以緩存集群會通過某種演算法將不同的數據放入到不同的機器中。

  3. 3. 不同持久化資料庫,一般來說,內存資料庫單機可以支持大量的增刪查改。

  4. 4. 如果一台機器支持不住,可以用主從復制,進行緩存的方法解決。

  5. 綜上,在這個場景下應用redis 進行讀寫分離,完全就失去了讀寫分離的意義。

㈡ 分布式系統中應用程序怎麼實現資料庫讀寫分離

本文實例分析了Yii實現Mysql多資料庫和讀寫分離的方法。分享給大家供大家參考。具體分析如下: Yii Framework是一個基於組件、用於開發大型 Web 應用的高性能 PHP 框架。Yii提供了今日Web 2.0應用開發所需要的幾乎一切功能,也是最強大的框架之一,下文我們來介紹Yii實現MySQL多庫和讀寫分離的方法 前段時間為SNS產品做了架構設計,在程序框架方面做了不少相關的壓力測試,最終選定了YiiFramework,至於為什麼沒選用公司內部的 PHP框架,其實理由很充分,公司的框架雖然是"前輩"們辛苦的積累,但畢竟不夠成熟,沒有大型項目的歷練,猶如一個涉世未深的年輕小伙。Yii作為一個 頗有名氣開源產品,必定有很多人在使用,意味著有一批人在維護,而且在這之前,我也使用Yii開發過大型項目,Yii的設計模式和它的易擴展特性足以堪當重任。 SNS同一般的社交產品不同的就是它最終要承受大並發和大數據量的考驗,架構設計時就要考慮這些問題, web分布式、負載均衡、分布式文件存儲、MySQL分布式或讀寫分離、NoSQL以及各種緩存,這些都是必不可少的應用方案,本文所講的就是MySQL 分庫和主從讀寫分離在Yii的配置和使用。 Yii默認是不支持讀寫分離的,我們可以利用Yii的事件驅動模式來實現MySQL的讀寫分離。 Yii提供了一個強大的CActiveRecord資料庫操作類,通過重寫getDbConnection方法來實現資料庫的切換,然後通過事件 beforeSave、beforeDelete、beforeFind 來實現讀寫伺服器的切換,還需要兩個配置文件dbconfig和modelconfig分別配置資料庫主從伺服器和model所對應的資料庫名稱,附代碼 DBConfig.php文件如下: 復制代碼 代碼如下:<?php return array( 'passport' => array( 'write' => array( 'class' => 'CDbConnection', 'connectionString' => 'mysql:host=10.1.39.2;dbname=db1′, 'emulatePrepare' => true, //'enableParamLogging' => true, 'enableProfiling' => true, 'username' => 'root', 'password' => '', 'charset' => 'utf8′, 'schemaCachingDuration'=>3600, ), 'read' => array( array( 'class' => 'CDbConnection', 'connectionString' => 'mysql:host=10.1.39.3;dbname=db1, 'emulatePrepare' => true, //'enableParamLogging' => true, 'enableProfiling' => true, 'username' => 'root', 'password' => '', 'charset' => 'utf8′, 'schemaCachingDuration'=>3600, ), array( 'class' => 'CDbConnection', 'connectionString' => 'mysql:host=10.1.39.4;dbname=db3′, 'emulatePrepare' => true, //'enableParamLogging' => true, 'enableProfiling' => true, 'username' => 'root', 'password' => '', 'charset' => 'utf8′, 'schemaCachingDuration'=>3600, ), ), ), ); ModelConfig.php如下: 復制代碼 代碼如下:<?php return array( //key為資料庫名稱,value為Model 'passport' => array('User','Post'), 'microblog' => array('…'), ); ?> ActiveRecord.php如下: 復制代碼 代碼如下:/** * 基於CActiveRecord類的封裝,實現多庫和主從讀寫分離 * 所有Model都必須繼承些類. * */ class ActiveRecord extends CActiveRecord { //model配置 public $modelConfig = ''; //資料庫配置 public $dbConfig = ''; //定義一個多資料庫集合 static $dataBase = array(); //當前資料庫名稱 public $dbName = ''; //定義庫類型(讀或寫) public $dbType = 'read'; //'read' or 'write' /** * 在原有基礎上添加了一個dbname參數 * @param string $scenario Model的應用場景 * @param string $dbname 資料庫名稱 */ public function __construct($scenario='insert', $dbname = '') { if (!empty($dbname)) $this->dbName = $dbname; parent::__construct($scenario); } /** * 重寫父類的getDbConnection方法 * 多庫和主從都在這里切換 */ public function getDbConnection() { //如果指定的資料庫對象存在則直接返回 if (self::$dataBase[$this->dbName]!==null) return self::$dataBase[$this->dbName]; if ($this->dbName == 'db'){ self::$dataBase[$this->dbName] = Yii::app()->getDb(); }else{ $this->changeConn($this->dbType); } if(self::$dataBase[$this->dbName] instanceof CDbConnection){ self::$dataBase[$this->dbName]->setActive(true); return self::$dataBase[$this->dbName]; } else throw new CDbException(Yii::t('yii','Model requires a "db" CDbConnection application component.')); } /** * 獲取配置文件 * @param unknown_type $type * @param unknown_type $key */ private function getConfig($type="modelConfig",$key="){ $config = Yii::app()->params[$type]; if($key) $config = $config[$key]; return $config; } /** * 獲取資料庫名稱 */ private function getDbName(){ if($this->dbName) return $this->dbName; $modelName = get_class($this->model()); $this->modelConfig = $this->getConfig('modelConfig'); //獲取model所對應的資料庫名 if($this->modelConfig)foreach($this->modelConfig as $key=>$val){ if(in_array($modelName,$val)){ $dbName = $key; break; } } return $dbName; } /** * 切換資料庫連接 * @param unknown_type $dbtype */ protected function changeConn($dbtype = 'read'){ if($this->dbType == $dbtype && self::$dataBase[$this->dbName] !== null) return self::$dataBase[$this->dbName]; $this->dbName = $this->getDbName(); if(Yii::app()->getComponent($this->dbName.'_'.$dbtype) !== null){ self::$dataBase[$this->dbName] = Yii::app()->getComponent($this->dbName.'_'.$dbtype); return self::$dataBase[$this->dbName]; } $this->dbConfig = $this->getConfig('dbConfig',$this->dbName); //跟據類型取對應的配置(從庫是隨機值) if($dbtype == 'write'){ $config = $this->dbConfig[$dbtype]; }else{ $slavekey = array_rand($this->dbConfig[$dbtype]); $config = $this->dbConfig[$dbtype][$slavekey]; } //將資料庫配置加到component中 if($dbComponent = Yii::createComponent($config)){ Yii::app()->setComponent($this->dbName.'_'.$dbtype,$dbComponent); self::$dataBase[$this->dbName] = Yii::app()->getComponent($this->dbName.'_'.$dbtype); $this->dbType = $dbtype; return self::$dataBase[$this->dbName]; } else throw new CDbException(Yii::t('yii','Model requires a "changeConn" CDbConnection application component.')); } /** * 保存數據前選擇 主 資料庫 */ protected function beforeSave(){ parent::beforeSave(); $this->changeConn('write'); return true; } /** * 刪除數據前選擇 主 資料庫 */ protected function beforeDelete(){ parent::beforeDelete(); $this->changeConn('write'); return true; } /** * 讀取數據選擇 從 資料庫 */ protected function beforeFind(){ parent::beforeFind(); $this->changeConn('read'); return true; } /** * 獲取master庫對象 */ public function dbWrite(){ return $this->changeConn('write'); } /** * 獲取slave庫對象 */ public function dbRead(){ return $this->changeConn('read'); } } 這是我寫好的類,放在components文件夾里,然後所有的Model都繼承ActiveRecord類就可以實現多庫和主從讀寫分離了,至於如何支持原生的SQL也同時使用讀寫分離,此類都已經實現。 希望本文所述對大家基於Yii框架的PHP程序設計有所幫助。

㈢ mysql讀寫分離和用Redis做緩存,這兩種方案有什麼異同

讀寫分離一般都是結合Master/Slave模式使用,Master處理寫請求,Slave處理讀請求,這樣做的好處是:
1、提高資料庫的並發處理能力;
2、避免寫請求鎖表阻塞讀請求;
3、避免單點,提高資料庫的可用性;
而使用Redis作為DB前面的緩存,是為了減少對MySQL的壓力,提高系統的處理效率。

二者解決的問題域不同,不存在誰替代誰。

一般高並發應用都是結合二者使用。

㈣ rediscluster讀寫分離有什麼好處

先來討論一下為什麼要讀寫分離. 如果一台機器支持不住:
1。
4,完全就失去了讀寫分離的意義,常見的應用場景下我覺得redis沒必要進行讀寫分離。
2,一般來說。
過多的select會阻塞住資料庫,避免拒絕服務的發生,怎麼以更快的速度得到數據. 緩存
2。
因而通過讀寫分離:寫請求在可接受范圍內。

再來討論一下redis常見的應用場景,從而增加了讀的性能. 不同持久化資料庫:
讀寫分離使用於大量讀請求的情況,資料庫會拒絕服務。
3,可以用主從復制. 單機的內存資源是很有限的. 緩存主要解決的是用戶訪問時,通過多個slave分攤了讀的壓力:
1,這也是非常常見的應用場景,在這個場景下應用redis 進行讀寫分離,所以緩存集群會通過某種演算法將不同的數據放入到不同的機器中,從而增加性能,使你增刪改不能執行. 排名型的應用,但讀請求要遠大於寫請求的場景,而且到並發量過大時。
我認為需要讀寫分離的應用場景是. 實時消息系統

首先說一下緩存集群,訪問計數型應用
3。
綜上,內存資料庫單機可以支持大量的增刪查改,進行緩存的方法解決首先說結論:這個要跟你具體的架構實現以及業務相關

㈤ 如何處理資料庫並發問題

想要知道如何處理數據並發,自然需要先了解數據並發。

什麼是數據並發操作呢?
就是同一時間內,不同的線程同時對一條數據進行讀寫操作。

在互聯網時代,一個系統常常有很多人在使用,因此就可能出現高並發的現象,也就是不同的用戶同時對一條數據進行操作,如果沒有有效的處理,自然就會出現數據的異常。而最常見的一種數據並發的場景就是電商中的秒殺,成千上萬個用戶對在極端的時間內,搶購一個商品。針對這種場景,商品的庫存就是一個需要控制的數據,而多個用戶對在同一時間對庫存進行重寫,一個不小心就可能出現超賣的情況。

針對這種情況,我們如何有效的處理數據並發呢?

第一種方案、資料庫鎖
從鎖的基本屬性來說,可以分為兩種:一種是共享鎖(S),一種是排它鎖(X)。在MySQL的資料庫中,是有四種隔離級別的,會在讀寫的時候,自動的使用這兩種鎖,防止數據出現混亂。

這四種隔離級別分別是:

讀未提交(Read Uncommitted)
讀提交(Read Committed)
可重復讀(Repeated Read)
串列化(Serializable)
當然,不同的隔離級別,效率也是不同的,對於數據的一致性保證也就有不同的結果。而這些可能出現的又有哪些呢?

臟讀(dirty read)

當事務與事務之間沒有任何隔離的時候,就可能會出現臟讀。例如:商家想看看所有的訂單有哪些,這時,用戶A提交了一個訂單,但事務還沒提交,商家卻看到了這個訂單。而這時就會出現一種問題,當商家去操作這個訂單時,可能用戶A的訂單由於部分問題,導致數據回滾,事務沒有提交,這時商家的操作就會失去目標。

不可重復讀(unrepeatable read)

一個事務中,兩次讀操作出來的同一條數據值不同,就是不可重復讀。

例如:我們有一個事務A,需要去查詢一下商品庫存,然後做扣減,這時,事務B操作了這個商品,扣減了一部分庫存,當事務A再次去查詢商品庫存的時候,發現這一次的結果和上次不同了,這就是不可重復讀。

幻讀(phantom problem)

一個事務中,兩次讀操作出來的結果集不同,就是幻讀。

例如:一個事務A,去查詢現在已經支付的訂單有哪些,得到了一個結果集。這時,事務B新提交了一個訂單,當事務A再次去查詢時,就會出現,兩次得到的結果集不同的情況,也就是幻讀了。

那針對這些結果,不同的隔離級別可以干什麼呢?

「讀未提(Read Uncommitted)」能預防啥?啥都預防不了。

「讀提交(Read Committed)」能預防啥?使用「快照讀(Snapshot Read)」方式,避免「臟讀」,但是可能出現「不可重復讀」和「幻讀」。

「可重復讀(Repeated Red)」能預防啥?使用「快照讀(Snapshot Read)」方式,鎖住被讀取記錄,避免出現「臟讀」、「不可重復讀」,但是可能出現「幻讀」。

「串列化(Serializable)」能預防啥?有效避免「臟讀」、「不可重復讀」、「幻讀」,不過運行效率奇差。

好了,鎖說完了,但是,我們的資料庫鎖,並不能有效的解決並發的問題,只是盡可能保證數據的一致性,當並發量特別大時,資料庫還是容易扛不住。那解決數據並發的另一個手段就是,盡可能的提高處理的速度。

因為數據的IO要提升難度比較大,那麼通過其他的方式,對數據進行處理,減少資料庫的IO,就是提高並發能力的有效手段了。

最有效的一種方式就是:緩存
想要減少並發出現的概率,那麼讀寫的效率越高,讀寫的執行時間越短,自然數據並發的可能性就變小了,並發性能也有提高了。

還是用剛才的秒殺舉例,我們為的就是保證庫存的數據不出錯,賣出一個商品,減一個庫存,那麼,我們就可以將庫存放在內存中進行處理。這樣,就能夠保證庫存有序的及時扣減,並且不出現問題。這樣,我們的資料庫的寫操作也變少了,執行效率也就大大提高了。

當然,常用的分布式緩存方式有:Redis和Memcache,Redis可以持久化到硬碟,而Memcache不行,應該怎麼選擇,就看具體的使用場景了。

當然,緩存畢竟使用的范圍有限,很多的數據我們還是必須持久化到硬碟中,那我們就需要提高資料庫的IO能力,這樣避免一個線程執行時間太長,造成線程的阻塞。

那麼,讀寫分離就是另一種有效的方式了
當我們的寫成為了瓶頸的時候,讀寫分離就是一種可以選擇的方式了。

我們的讀庫就只需要執行讀,寫庫就只需要執行寫,把讀的壓力從主庫中分離出去,讓主庫的資源只是用來保證寫的效率,從而提高寫操作的性能。

㈥ java怎麼實現讀寫分離 數據一致性

讀寫分離一般用在資料庫和緩存的架構設計方面。讀庫只負責返回查詢結果,寫庫只負責更新和增加,然後兩個庫實時同步。一般系統的讀壓力比寫壓力大的多,這樣可以設計多個讀庫分擔查詢的壓力。

㈦ redis sentinel 能實現讀寫分離嗎

首先說結論:這個要跟你具體的架構實現以及業務相關,常見的應用場景下我覺得redis沒必要進行讀寫分離。

先來討論一下為什麼要讀寫分離:
讀寫分離使用於大量讀請求的情況,通過多個slave分攤了讀的壓力,從而增加了讀的性能。
過多的select會阻塞住資料庫,使你增刪改不能執行,而且到並發量過大時,資料庫會拒絕服務。
因而通過讀寫分離,從而增加性能,避免拒絕服務的發生。
我認為需要讀寫分離的應用場景是:寫請求在可接受范圍內,但讀請求要遠大於寫請求的場景。

再來討論一下redis常見的應用場景:
1. 緩存
2. 排名型的應用,訪問計數型應用
3. 實時消息系統

首先說一下緩存集群,這也是非常常見的應用場景:
1. 緩存主要解決的是用戶訪問時,怎麼以更快的速度得到數據。
2. 單機的內存資源是很有限的,所以緩存集群會通過某種演算法將不同的數據放入到不同的機器中。
3. 不同持久化資料庫,一般來說,內存資料庫單機可以支持大量的增刪查改。
4. 如果一台機器支持不住,可以用主從復制,進行緩存的方法解決。
綜上,在這個場景下應用redis 進行讀寫分離,完全就失去了讀寫分離的意義。

㈧ memcache讀寫分離是要兩個資料庫嗎

讀寫分離一般都是結合Master/Slave模式使用,Master處理寫請求,Slave處理讀請求,這樣做的好處是: 1、提高資料庫的並發處理能力; 2、避免寫請求鎖表阻塞讀請求; 3、避免單點,提高資料庫的可用性; 而使用Redis作為DB前面的緩存,是為了減少...

㈨ 如何利用Spring實現資料庫讀寫分離

讀寫分離是為了減少資料庫的負荷,當用戶高並發訪問時,絕大部分都是用戶查詢,少部分用戶是寫入到資料庫的。這些我們把資料庫拆分成主從兩個資料庫,主資料庫用高性能

伺服器承載高並發的用戶訪問並加redis緩存。在這里我不講mysql的主從同步配置,大家可以去查下資料,我接下來重點講怎麼動態的給每個sql注入數據源。