原創做者,公衆號【程序員讀書】,歡迎關注公衆號,轉載文章請註明出處哦。git
影響服務器性能的因素有不少,好比CPU、內存、硬盤等硬件設備條件的限制,也有服務器總體架構、程序員的代碼質量、使用的算法和數據結構優劣等方方面面的因素。程序員
不過我的感受對服務器性能影響最大,應該是數據庫,服務器在面對高併發請求時,性能瓶頸每每出如今數據庫方面,由於數據庫扛不了那麼高的併發數,而使用數據庫集羣每每也意味着較高的硬件和軟件成本,所以,若是在代碼層與數據庫之間再加一層緩存,能夠有效緩解數據庫的壓力,大大提高服務器的性能。github
而提到緩存,咱們最早想到的是什麼,是Redis
,或許這就是Redis
給咱們的第一印象,雖然這樣理解Redis並不徹底正確,由於Redis
所能作,並不只僅於此,下面一塊兒探究一下吧。golang
Redis
是一名叫Salvatore Sanfilippo的人在2009年使用ANSI C
編寫的開源的內存數據結構存儲系統,Redis的做者開發Redis很大一部分緣由,也是由於數據庫沒法知足他的需求。redis
固然啦,咱們能夠把Redis簡單地理解爲內存數據庫(NoSQL)或者Key-Value鍵值對服務器。算法
Redis
提供了多種數據結構和不一樣編程語言的客戶端API
,另外,也提供了持久化、主從複製、事務等多種功能和特性,就像一把瑞士軍刀通常,是服務器開發中的一把利器。docker
雖然Redis
提供了很是強大的功能,但Redis
的代碼卻很是簡單,其最初的版本只有23000行代碼,而最近的某一個版本代碼也只有50000多行而已,所以,感興趣的人能夠研究一下Redis
源碼。數據庫
下面列出一些Redis
的特性,讓咱們對Redis
有個比較全面的瞭解,其實,從這些特性中,也能夠看出Redis
的強大。編程
Redis
的響應速度很是快,之因此這麼快,最大的緣由是Redis
對數據的操做都是在內存中進行的,咱們從下面的存儲器層次結構圖即可以看到,內存的讀寫速度比硬盤(不管是固態仍是機械硬盤)都在快不少,所以Redis天然就很是快速。windows
前面咱們說Redis
將數據放在內存中,,但Redis
也提供了持久化機制,這樣能夠將用戶存儲到內存中的數據,定時持久化到硬盤等存儲設備中,保證服務器斷電重啓時,數據不會消失,Redis
支持RDB
和AOF
兩種持久化機制,有機會,咱們在之後的文章中講講這兩種機制的區別。
Redis
支持多種類型的數據結構,這也是Redis
與Memcached
的區別之一,Memcached
只支持String
類型,而Redis
除了String
、Hash
、List
、Set
、Sort Set
這些基本的數據類型外,還有BitMaps(位圖)
、HyperLogLog(超小內存惟一值計數)
、GEO(地理信息定位)
等高級的數據類型。
Redis爲大多數編程語言都提供了客戶端API,這些API有些是官方提供的,有些則來自開源社區的貢獻,因此無論你使用什麼語言來開發服務器應用,均可以很方便鏈接Redis。
下面是Redis官網上列出全部編程語言API列表的地址
# redis支持的客戶端列表
https://redis.io/clients
複製代碼
Redis
支持訂閱與發佈的功能,所以可使用Redis
來實現一個簡單消息隊列,一端做爲發佈者把消息發佈到Redis
,而另外一端做爲消費者,處理來自Redis
的消息。
Redis
在V2.6u新增了腳本功能,容許客戶端使用Lua語言編寫腳本傳到Redis
中執行,這樣作的好處是:減小網絡開銷原子操做和腳本複用,關於Redis中如何使用Lua腳本,有空再說。
Redis支持事務,當咱們須要執行多條命令時,保證多條命令執行原子性,由於在事務中,多條命令的執行,要麼都成功,要麼都失敗,固然,要執行多個命令,使用Lua腳本也許更加方便。
Redis支持主從複製功能,即主服務器的數據,能夠同步到多臺從服務器上,因此主從複製實際是爲Redis的高可用和分佈式提供了基礎。
Redis也支持高可用和分佈式,實際主從複製只是實際高可用的基礎,但要經過主從複製實現高可用是不太可能的,Redis的高可用是經過Redis Sentinel(哨兵)
來實現的,Redis Sentinel是在V2.8增長的功能,而分佈式則須要Redis cluster
功能的支持,Redis_cluster
是在v3.0以後增長的功能。
Redis
是單線程的,這裏所說的單線程,指其在Redis做爲服務器在接收客戶端網絡請求時採用是單線程,因此在同一時刻,Redis沒法同時處理兩個請求,只有一個請求處理完成再處理下一個請求,不過Redis在實現某個功能時,仍是使用的多線程的,好比將數據持久化到硬件,就是開啓另外一個線程來實現的。
Redis
的安裝很是簡單,這裏介紹兩種安裝方式,一種是從Redis
官網上下載源碼,而後編譯安裝,另一種更加方便,直接從Docker Hub
上拉取Redis
的docker
鏡像。
下面介紹的是在Linux系統上安裝Redis的過程。
# 下載redis源碼安裝包
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
# 解壓縮
tar -zxvf redis-5.0.5.tar.gz
# 進入redis源碼目錄
cd redis-5.0.5
# 編譯 & 安裝
make && make install
複製代碼
Redis提供了docker鏡像,所以咱們能夠很方便拉取並運行Redis鏡像,不過,前提是你的服務器上有安裝docker
。
# 從Docker Hub上拉取官方鏡像,redis:latest
docker pull redis
# 從鏡像中啓動一個容器
docker run --name my_redis -p 6379:6379 -d redis
複製代碼
這裏要說明一點,就是Redis做者並無開發Redis的Windows版本,可能Redis的做者以爲安裝Windows系統的服務器不適合運行Redis,又或者什麼緣由,不過微軟仍是提供了Redis的Windows版本。
# redis的windows版本
https://github.com/microsoftarchive/redis/releases
複製代碼
不帶參數,使用默認配置啓動服務器
# 使用默認配置啓動
redis-server
複製代碼
指定命令行參數啓動服務器
# 使用命令參數配置啓動
redis-server --port 6380
複製代碼
使用配置文件啓動服務器
# 使用配置文件啓動
redis-server ~/redis-5.0.5/redis.conf
複製代碼
在使用前面介紹的幾種方式啓動Redis服務器後,咱們就可使用Redis客戶端鏈接服務器,向服務器寫入或讀取數據,前面咱們說過Redis支持大多數編程語言,所以大你們能夠根據本身的狀況選擇不一樣的API。
在安裝好Redis以後,就可使用Redis安裝包中自帶的客戶端redis-cli
,這是一個命令行客戶端,其使用示例以下:
# 直接使用,不帶參數,會鏈接本地服務器
redis-cli
# 指定地址和端口號
redis-cli -h 服務器地址 -p 端口號
複製代碼
在這裏演示使用golang
的開發的redigo/redis
包鏈接Redis
服務器。
# 獲取go語言的某個redis客戶端庫
go get github.com/gomodule/redigo/redis
複製代碼
下面是使用redigo/redis
庫鏈接Redis的簡單代碼示例:
package main
import (
"fmt"
"github.com/gomodule/redigo/redis"
)
var redisCon redis.Conn
func main() {
var err error
redisCon ,err = redis.Dial("tcp","localhost:6379")
if err != nil{
panic(err)
}
defer redisCon.Close()
rs,err := redisCon.Do("set","test_key","test_value")
if err != nil{
panic(err)
}
fmt.Println(rs)
}
複製代碼
上面的代碼可能比較簡單,有機會咱們詳細瞭解如何使用Golang更好地鏈接和操做Redis。
下面列出一些Redis
的使用場景,咱們也能夠根據本身的須要,靈活使用Redis
來達到提高服務器性能的目的。
Redis
最常被使用的場景就是用於數據緩存,因爲其基於內存的數據快速讀寫操做,響應速度很是快,能夠用於緩存一些熱點數據或者不怎麼變化的數據,這樣,當用戶請求這些數據時,直接從Redis
快速讀取,避免頻繁的數據庫讀寫,提高服務器的數據吞吐量及速度。
Redis
的sort set
數據類型很是適合作排榜行功能,好比【掘金】的【推薦做者榜】其實實現的原理應該就是將計算後的做者排行權重放在Redis
的sort set
中來實現的,所以Redis
在實現這類功能真的是很是方便簡單。
Redis的功能與一些社區功能有着自然的契合性,使用Redis所支持的數據結構,能夠容易存儲社區功能中的如關注數,粉絲數,關注列表,粉絲列表,共同共注等數據,好比關注數與粉絲數能夠用計數器,關注列表和粉絲列表可使用set
o類型來存儲。
Redis
內置的incr
命令能夠很方便地單線程下進行計數,並且這種操做是原子性,不用擔憂某個時刻有兩個請求對同一個鍵值進行計數,這種計數器功能在某些場景下很是實用,好比掘金的文章,閱讀數、評論數、點贊數可使用Redis的計數功能來實現,想一想,若是這些數據直接寫入數據庫,那麼每次有人點贊、閱讀、評論都須要對數據庫進行操做,估計數據庫會掛掉,而使用Redis計數功能,則能夠快速輕鬆完成這種功能的實現。
Redis
支持發佈訂閱功能,所以能夠把Redis
看成一個簡單的消息隊列,當咱們有一些業務須要使用消息隊列時,能夠考慮使用Redis
來實現,固然,成熟的消息隊列中間件系統有不少,如Kafka
,RabbitMQ
,RocketMQ
,ActiveMQ
,而後使用這些可能須要額外的軟硬件成本及學習成本,所以可使用Redis
的消息隊功能來替代。
對於一些須要實時處理的數據,也能夠直接寫入Redis
中,再由其餘系統進行處理,這其實也是利用了Redis
發佈訂閱的功能,來達到數據實時處理的目的,好比一些垃圾郵箱處理系統等。
在這篇文章中,咱們簡單地談了一下Redis
是什麼,能夠作什麼,並瞭解其強大的特性和功能,經過演示如何安裝、啓動和鏈接Redis
,也讓咱們知道如何使用Redis
,固然啦,想要更好地瞭解和使用Redis
,還須要更加深刻地學習,下面有機會,咱們繼續這方面的學習。
你的關注,是我寫做路上最大的鼓勵!