學習Redis(一)

1、NoSQL概述

not only SQL,非關係型數據庫,它能解決常規數據庫的併發,如傳統的數據庫的IO與性能的瓶頸,一樣也是關係型數據庫的一個補充,有較好的高效率與高性能。php

一、解決如下問題:前端

1)對數據庫的高併發讀寫需求
2)大數據的高效存儲和訪問需求
3)高可擴展性和高可用性的需求
二、Nosql數據庫的應用環境python

1)數據模型比較簡單
2)須要靈活性更強的IT系統
3)對數據庫的性能要求較高
4)不須要高度數據一致性
5)對於給定KEY,比較容易映射覆雜值的環境mysql

三、Nosql軟件的分類與特色git

1)key-value鍵值存儲數據庫(redis、memcached、ttserver)   可經過key來添加、查詢、刪除數據github

1.用於內容緩存,適合負載並擴展大的數據集redis

2.數據類型是一系列的鍵值對算法

3.有快速查詢功能,但存儲數據少結構化sql

4.對事務的支持很差,數據庫故障產生時不可進行回滾數據庫

適用場景:存儲用戶信息,如會話、配置文件、參數、購物車、計數(統計粉絲關注)等

2)列存儲數據庫(HBase)     查詢多個列

1.用於分佈式的文件系統

2.以列簇式存儲,將同一列數據存在一塊兒

3.查找速度快,可擴展強,更容易進行分佈式擴展

4.功能相對侷限

適用場景:日誌(將信息寫入本身的column family中);blog平臺(存儲到不一樣的column family中,如標籤、類別、文章等);

3)面向文件的數據庫(mongoDB)     版本化的文檔,半結構化的文檔

1.用於WEB應用較多

2.數據類型是一系列鍵值對

3.查詢性能不高,沒有統一的查詢語法

適用場景:日誌(程序有不一樣的日誌);無固定的模式,存儲不一樣的信息;分析(不改變模式就可存儲不一樣的度量方法及添加新的度量)

4)圖形數據庫(Graph)  數據已圖的方式存儲

1.社交網絡應用較多

2.不容易作分佈式的集羣方案

經常使用的Nosql數據庫介紹

適用場景:在關係型強的數據中;推薦引擎,若將數據以圖的形式表現,會很是有益於推薦的制定

四、經常使用的Nosql數據庫介紹

1)memcached

是一個開源高性能的,具備分佈式內存對象的緩存系統

特色:

 一、安裝佈署簡單

二、支持高併發、高性能
三、經過程序或負載均衡能夠實現分佈式
四、僅爲內存緩存,重啓服務數據丟失

2)memcacheDB

是新浪基於memcached開發的一個開源項目,具有了事務恢復功能

特色:

一、高併發讀寫
二、高效存儲
三、高可用數據存儲

3)ttserver(tokyo tyrant/tokyocabinet)

是日本人開發的一款DBM數據庫,該DB的rw很是快,是BDB的幾倍,哈希模式寫入100萬條數據只需0.643s,讀100萬條數據只需0.773s

特色:

一、不但支持內存緩存還可持久化存儲;

二、故障轉移,tokyo tyrant支持主從模式,也支持雙機互爲主從模式,主從庫都可rw;

三、5KW條數據級別內的訪問至關快;

四、兼容memcached協議,客戶端不需更改任何代碼;

4)mongoDB(document-oriented)

是一個基於分佈式文件存儲的數據庫。由C++語言編寫

特色(易部署、高性能、易使用、存儲數據很是方便);

5)redis(key-value)

是一個開源的使用ANSIC語言編寫(代碼3W多行)、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API

1)支持內存緩存,至關於memcached;

2)持久化,至關於memcachedb,ttserver;

3)數據類型更豐富;

4)支持集羣,分佈式;

五、生產環境如何選擇Nosql數據庫

1)最常規的緩存應用,memcached最合適
2)持久化存儲方案memcacheDB
3)2000萬之內數據量的小數據用memcached
4)大數據量能夠用redis

2、redis概述

redis是一種 持久化緩存服務 ,會週期的把更新的數據寫入磁盤以及把修改操做記錄追加到文件裏記錄下來,還 支持主從同步模式 ,是一個開源的基於C語言編寫的,支持網絡、內存可持久化的日誌型、key-value數據庫

  • http://www.redis.cn/
  • http://www.redis.io/topics/introduction

一、redis持久服務的特色

key-value鍵值類型存儲系統

支持數據可靠存儲

單進程單線程高性能服務器

恢復比較慢

單機qps(秒併發)能夠達到10W

適合小數據高速讀寫訪問

redis存儲系統優、缺點:

能夠持久化存儲數據

支持每秒10W的讀寫頻率

支持豐富的數據類型

全部操做都是原子性的

支持異機主從複製

內存管理開銷大(低於物理內存的3/5)

不一樣命令延遲差異大

二、redis持久化介紹

redis將 數據存儲於內存中 ,經過 快照、日誌 兩種方式實現持久化存儲,前者性能高,會有數據丟失的狀況,後者相反。

snapshot(快照):一次性將內存中的數據寫入到磁盤,或使用相似MySQL的binlog日誌 

aof 方式:記錄每次更新的日誌,不會致使數據的丟失;(不用於主從同步)僅僅用於保存數據;

#名詞解釋
#Snapshot(快照)
save 900 1      #900秒有1key容量被更新,則觸發快照寫入磁盤
save 300 10
save 60 10000

#AOF(更新日誌)
appendfsync always  #老是記錄更新內容
appendfsync everysec    #每秒記錄更新內容
appendfsync no  #不記錄更新內容

若是選擇了快照的策略,那麼快照在每次進行保存的時候,都會阻礙執行前端的客戶端請求

三、 redis的數據類型

String 字符串

Hash 哈希表

List 列表

Set 集合

Sorted set 有序集合

四、redis應用場景

1)redis所有數據在memory

2)最佳對memcached的替代品;

3)數據比較重要,對數據一致性有必定要求的業務;

4)當須要除key/value以外的更多數據類型支持時,使用redis更合適;

5)須要提供主從同步以及負載均衡分佈式應用場景(redis主從同步);

6)計數,cache服務,展現最近,最熱,點擊率最高,活躍度最高等等條件的top list,用戶最近訪問記錄,Relation List/Message Queue,粉絲列表

 五、redis的應用案例

1)應用程序-->redis

2)應用程序首先訪問Redis,只有當Redis沒有數據或訪問失敗時訪問MySQL 

3)二次開發實現MySQL和redis互相同步

六、redis的生產經驗教訓

1)要進行master-slave主從同步配置,在出現服務故障時能夠切換;

2)在master禁用數據持久化,只需在slave上配置數據持久化;

3)物理內存+虛擬內存不足,這個時候dump一直死着,時間久了機器掛掉

4)當redis物理內存使用超過內存總容量的3/5時就會開始比較危險了,就開始作swap,內存碎片大!

5)當達到最大內存時,會清空帶有過時時間的key,即便key未到過時時間;

6)redis與db同步寫的問題,先寫db,後寫redis,由於寫內存基本上沒有問題;

3、redis部署

 一、安裝redis

wget http://download.redis.io/releases/redis-2.8.24.tar.gz
tar zxf redis-2.8.24.tar.gz
cd redis-2.8.24
make
make PREFIX=/application/redis-2.8.24 install

二、相關命令做用

redis-server        #Redis服務器的daemon啓動程序
redis-cli           #Redis命令操做工具。固然,你也能夠用telnet根據其純文本協議來操做
redis-benchmark     #Redis性能測試工具,測試Redis在你的系統及你的配置下的讀寫性能。
redis-check-aof     #對更新日誌appendonly.aof檢查,是否可用,相似檢查mysql binlog的工具
redis-check-dump    #用於本地數據庫rdb文件的檢查

三、啓動服務

1、查看命令幫助
redis-server -h
2、從源程序目錄複製redis.conf到安裝目錄
cp  redis-2.8.24/redis.conf   /application/redis/conf/
3、啓動服務
redis-server /application/redis/conf/redis.conf &
四、關閉服務
redis-cli shutdown
redis-cli shutdown save

啓動後,會出現警告:若是內存不夠的狀況下後臺保存可能會失敗

 解決方法:

1、永久生效
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
sysctl -p 
2、臨時生效
sysctl vm.overcommit_memory=1

vm.overcommit_memory參數說明:
0:當用戶空間請求更多的內存時,內核嘗試估算出剩餘可用的內存。
1:當設這個參數值爲1時,內核容許超量使用內存直到用完爲止,主要用於科學計算
2:當設這個參數值爲2時,內核會使用一個毫不過量使用內存的算法,即系統整個內存地址空間不能超過swap+50%的RAM值,50%參數的設定是在overcommit_ratio中設定。

四、相關命令

redis-cli      鏈接本地redis
set id 001     寫入一條數據
get id         取值
del id         刪除
exists id      驗證key是否存在
keys *         查看redis裏全部的key
select 1       切換到表1模式(默認有16個庫,沒法看到,庫的數量可在redis.conf中配置)

五、redis-cli客戶端的遠程鏈接及非交互式操做數據庫 

redis-cli -h 10.0.0.135 -p 6379

redis-cli -h 10.0.0.135 -p 6379 set aaa 111
redis-cli -h 10.0.0.135 -p 6379 get aaa

telnet 10.0.0.135 6379

echo "set no004 zsq"|nc 127.0.0.1 6379
echo "get no004 "|nc 127.0.0.1 6379

六、redis命令幫助 

1)redis-cli客戶端命令幫助:
10.0.0.135:6379> ?              #查看幫助命令用法
10.0.0.135:6379> help           #查看幫助命令用法
10.0.0.135:6379> help set       #查看set命令用法

2)經過help命令來查找命令
10.0.0.135:6379> help @generic  #這裏須要狂按Tab鍵
                 輸入help + 空格 + 屢次<Tab>鍵來切換全部命令

七、redis安全

 1)設置密碼

redis沒有用戶的概念,客戶端能夠在1秒內進行上萬次的密碼嘗試,要設置強大的密碼來防止暴力破解
339:# requirepass    密碼

redis-cli  shutdown  save
redis-server /usr/local/redis/conf/redis.conf &

第一種登錄驗證方式
redis-cli 
auth yunjisuan       提交驗證密碼
keys *                   查看全部keys

第二種登陸驗證方式
redis-cli -a 密碼       登錄時提交密碼

2)將危險的命令更名

1、修改配置文件
359  rename-command set "sset"
2、重啓redis進程 redis-cli -a 密碼 shutdown redis-server /usr/local/redis/conf/redis.conf &
3、驗證命令更名效果 redis-cli -a 密碼 sset xxx 555 寫入key-value正確 get xxx
4、其餘 rename-command set "" 好比屏蔽這個set

 八、爲php安裝redis客戶端擴展 

1)獲取源碼包
wget https://github.com/nicolasff/phpredis/archive/master.zip

2)安裝
unzip    phpredis-master.zip
cd        phpredis-master
/application/php/bin/phpize
./configure --with-php-config=/application/php/bin/php-config
make && make install

3)檢查
ls    /application/php-5.6.8/lib/php/extensions/no-debug-non-zts-20131226/
memcache.so  opcache.a  opcache.so  redis.so

4)修改php.ini設置,重啓php
echo   "extension = redis.so" >> /application/php/lib/php.ini
#將php.ini配置文件中的extension_dir修改爲以下:
extension_dir = "/application/php-5.6.8/lib/php/extensions/no-debug-non-zts-20131226/" 
killall php
-fpm
/application/php/sbin/php-fpm

  九、php程序實戰操做redis服務 

必需要有php環境
cat /application/php/bin/php 1.php
<?php
     $redis = new Redis();
     $redis ->connect('192.168.179.162',6379);
     $redis ->auth('zsq');
     $redis ->set('name','zsq');
     $var = $redis ->get('name');
     echo "$var\n";
?>

  十、安裝Python redis客戶端操做redis

wget https://pypi.python.org/packages/source/r/redis/redis-2.10.1.tar.gz
tar xf redis-2.10.1.tar.gz
cd redis-2.10.1
python setup.py install

  開發python程序操做redis

# python
>>> import redis            #引用redis支持庫
>>> r = redis.Redis(host='10.0.0.135',port='6379',password='yunjisuan') #創建redis數據庫的鏈接對象(面向對象方式)
>>> r.set('name','benet')   #操做對象調用set方法寫入數據
>>> r.get('name')           #操做對象調用get方式讀取數據
>>> r.dbsize()              #操做對象查看redis數據庫的數據條數
>>> r.keys()                #查看全部的key>>> exit()                  #退出

  經過Web界面鏈接Python程序展現redis

# cat python-redis.py 
#/usr/bin/python

from wsgiref.simple_server import make_server
import redis

def get_redis():
    r = redis.Redis(host='10.0.0.135',port='6379',password='yunjisuan',db=0)
    r.set('name','yunyunyun')
    return r.get('name')
    
def hello_world_app(environ,start_response):
    status = '200 OK'   #HTTP Status
    headers = [('Content-type','text/plain')]   #HTTP Headers
    start_response(status,headers)
    
    # The returned object is going to be printed
    return get_redis()

httpd = make_server('',8000,hello_world_app)
print "Serving on port 8000..."

# Server until process is killed
httpd.serve_forever()

  啓動python腳本

# python python-redis.py 
Serving on port 8000...     #監聽8000端口

經過客戶端瀏覽器鏈接Python程序
127.0.0.1:8000

十一、解讀redis默認配置文件 

#redis支持include功能
30 include /path/to/local.conf
31 include /path/to/other.conf

#redis是否後臺運行
37 daemonize no   

#pid號保存文件的位置
41 pidfile /var/run/redis.pid

#redis默認監聽端口
45 port 6379

#調整tcp監聽隊列
54 tcp-backlog 511

#調整redis的監聽地址
63 bind 192.168.1.100 10.0.0.1
64 bind 127.0.0.1

#調整客戶端超時時間
74 timeout 0

#調整tcp的會話保持時間
90 tcp-keepalive 0

#調整日誌級別
98 loglevel notice

#redis日誌記錄位置,默認是打印到屏幕上
103 logfile "" #是否啓用syslog來接收日誌(好比日誌集中收集) 113 syslog
-facility local0 #設置數據庫的數量,若是缺省,默認爲0(select0...select 15) 118 databases 16

#redis快照設置
140  #save ""      #若是不想保存在磁盤,就如此設置
142  save 900 1      #900秒內至少1key數據變化,但會阻塞用戶請求,高併發時不用 143  save 300 10     #300秒內至少10key數據變化,但會阻塞用戶請求,高併發時不用
144  save 60 10000   #60秒內至少10000key數據變化,但會阻塞用戶請求,高併發時不用
#若是bgsave出錯是否中止寫入 159 stop
-writes-on-bgsave-error yes #redis將數據存儲在磁盤的什麼位置 177 dbfilename dump.rdb #指定redis配置文件當前工做的路徑(指定dbfilename的當前路徑位置) 187 dir ./ #給redis設定密碼 339 requirepass 123456 #修改redis操做命令的名稱 355 rename-command CONFIG "" 356 rename-command set "" 357 rename=command get wk #設定redis內存限制(可是內存用完後,redis就會開始刪除key) 398 maxmemory <bytes> #設定redis內存清理的算法 403 # volatile-lru -> remove the key with an expire set using an LRU algorithm 404 # allkeys-lru -> remove any key accordingly to the LRU algorithm 405 # volatile-random -> remove a random key with an expire set 406 # allkeys-random -> remove a random key, any key 407 # volatile-ttl -> remove the key with the nearest expire time (minor TTL) 408 # noeviction -> don't expire at all, just return an error on write operation

#設定redis內存限制及內存清理的算法示例 421 maxmemory-policy volatile-lru

#是否啓用AOF存儲模式
451 appendonly no

#設定AOF文件的存儲位置
455 appendfilename "appendonly.aof" #並不用於主從同步,只是redis在啓動時,讀取此文件用於恢復數據

#設定AOF同步存儲的時間週期
481 appendfsync everysec #每秒或不用

#自動保持rewrite
522 auto-aof-rewrite-percentage 100
523 auto-aof-rewrite-min-size 64mb

#lua腳本實現更多生產場景
541 lua-time-limit 5000

#hash優化參數
hash-max-ziplist-entries 512
hash-max-ziplist-value 64

 4、redis數據類型

key建議:長度10到20

value建議:String 不要超過2k,集合和有序集合不要超過5k

Redis支持五種數據類型string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

一、String字符串類型

string是redis最基本的類型,一個key對應一個value,string類型是二進制安全的,包含任何數據,但值的長度不能超過1GB

1)String類型也能夠用來存儲數字,並支持對數字的加減操做:

set id 1          #設置鍵爲id 值爲1
get id            #查數據
incr id           #自動自增長1
incrby id 5     #自動自增指定數值    
decr id           #自動自減1
decrby id5        #自動自減指定數值   

 2)爲key設置新值而且返回原值

getset user01 wangwu    #設置新數據並返回舊數據
get user01      

3)String類型還支持批量讀寫操做

mset name zhangsan age 44
mget name age

 4)string類型還支持對其部分的修改和獲取操做

append  images .jpg       #追加字符串
strlen  images            #計算字符串長度
substr  images 0 6        #取0到6的值

 5)命令使用幫助

#查看單個命令help+命令名
help set
#查看字符串全部命令
help @string

 二、List類型

Redis 列表是簡單的字符串列表,按照插入順序排序。你能夠添加一個元素導列表的頭部(左邊)或者尾部(右邊)。
lpush   students "zhangsan"     #將元素「zhangsan」放在students列表的最左邊
lpush   students "wangwu"       #將元素「wangwu」插入列表的最左邊
lrange  students 0 1            #查看序列是0到1的元素
rpush   students "wangyue"      #將元素wangyue插入列表的最右邊
llen    students                #查看列表元素的個數
lpop    students                #移除最左邊的元素值
rpop    students                #移除最右邊的元素值
lrem    students 2 "zhangsan"   #刪除列表裏是「zhangsan」的元素,刪除兩次(從左向右刪)
lrem    students 1 "zhangsan"   #刪除列表裏的元素zhangsan一次
lrem    students 0 "zhangsan"   #清空列表全部的zhangsan元素
linsert students before b xxxx  #在元素b的前邊插入元素xxxx
linsert students after b xxxx   #在元素b的後邊插入元素xxxx
更多操做,請查詢help @list

list可實現聊天系統。還能夠做爲不一樣進程間傳遞消息的隊列。

三、集合(Sets)類型

Redis的Set是string類型的無序集合,集合內的元素具備惟一性,集合是經過哈希表實現的,因此添加,刪除,查找的複雜度都是O(1)。

sadd users laoda           #向集合users裏添加一個元素「laoda」
sadd users laoer laosan    #向結合users裏添加兩個元素laoer,laosan
smembers  users            #查看集合裏的全部元素(看到集合裏的元素是無序的)
sismember users laoda      #查看元素laoda是否存在於集合users中
###更多操做,請查詢help @set

四、有序集合(Sorted Sets)類型

redis經過分數來爲集合中的成員進行從小到大的排序。

#向一個有序集合裏添加元素
zadd hackers 1940 "1940-Alan Kay"           #hackers是有序集合名,1940是序號,1940-Alan Kay是值
zadd hackers 1969 "1969-Linus Torvalds"
zadd hackers 1912 "1912-Alan Turing"
#ZADD建立的集合是有序集合。
zrange hackers 0 6                          #查看集合索引0到6的元素
zrevrange hackers 0 -1                      #利用zrevrange進行反向查詢
#查看有序集合days的具體值的排序
zscore  hackers "1969-Linus Torvalds"
zscore  hackers -inf 1912 #負無窮到1912之間的值
zscore  hackers 1912 1940 #1912到1960之間的值
###更多操做,請查詢help @sorted_set

五、Hash類型

Redis可以存儲key對多個屬性的數據(好比user1,uname user1.passwd)

#存儲一個hash類型test,他的屬性是name,屬性數據是yunjisuan
hset test name yunjisuan
#存儲一個hash類型test,他的屬性是age,屬性數據是35
hset test age 35
#存儲一個hash類型test,他的屬性是sex,屬性數據是non
hset test sex nan
#查看hash類型test的全部屬性的值
hvals test
#查看hash類型test的全部屬性及屬性所對應的值
hgetall test

5、redis多實例實戰

 一、建立redis多實例的存儲目錄及文件

#建立redis多實例存儲目錄
 mkdir -p /data/6380/data
 mkdir -p /data/6381/data

#建立redis多實例配置文件
 cp /usr/local/redis/conf/redis.conf /data/6380/ cp /usr/local/redis/conf/redis.conf /data/6381/

#修改多實例的數據存儲路徑
 sed -n '187p' /data/6380/redis.conf 
 dir /data/6380/data                 
 sed -n '187p' /data/6381/redis.conf 
 dir /data/6381/data                 

#修改多實例的佔用端口
 sed -n '45p' /data/6380/redis.conf 
 port 6380 sed -n '45p' /data/6381/redis.conf 
 port 6381                          

#修改多實例的pid文件位置
 sed -n '41p' /data/6380/redis.conf
 pidfile /data/6380/redis.pid            
 sed -n '41p' /data/6381/redis.conf
 pidfile /data/6381/redis.pid            

#開啓多實例的持久化日誌
 sed -n '449p' /data/6380/redis.conf 
 appendonly yes                      
 sed -n '449p' /data/6381/redis.conf 
 appendonly yes                      

二、啓動redis多實例

 redis-server /data/6380/redis.conf &
 redis-server /data/6381/redis.conf &

三、查看redis多實例的進程啓動狀況

 netstat -antup | grep redis

四、查看多實例文件夾目錄樹一覽

# tree /data
/data
├── 6380                        #redis實例6380啓動目錄
│   ├── data                    #redis實例6380數據目錄
│   │   ├── appendonly.aof      #redis實例6380的數據持久化日誌(記錄了數據庫的修改,相似binlog)
│   │   └── dump.rdb            #redis實例6380數據存儲文件
│   └── redis.conf              #redis實例6380配置文件
└── 6381                        
    ├── data                    
    │   ├── appendonly.aof      
    │   └── dump.rdb            
    └── redis.conf              

appendonly.aof:記錄咱們對redis數據庫的修改記錄,這點相似於MySQL的binlog日誌。

 6、 Redis主從同步

一、Redis主從同步特色

a、一個master能夠擁有多個slave

b、多個slave能夠鏈接同一個master,還能夠鏈接到其餘slave

c、主從複製不會阻塞master,在同步數據時,master能夠繼續處理client請求。

d、提升系統的伸縮性

二、Redis主從同步的過程

a、Slave服務器鏈接到Master服務器

b、Slave服務器發送SYNC命令

c、Master服務器備份數據庫到.rdb文件

d、Master服務器把.rdb文件傳輸給Slave服務器

e、Slave服務器把.rdb文件數據導入到數據庫中

三、Redis的主從同步具備明顯的分佈式緩存特色:

1)一個master能夠有多個slave,一個slave下面還能夠有多個slave
2)slave不只能夠鏈接到master,slave也能夠鏈接其餘slave造成樹狀。
3)主從同步不會阻塞master,可是會阻塞slave。當一個或多個slave與master進行初次同步數據時,master能夠繼續處理client發來的請求。相反slave在初次同步數據時則會阻塞不能處理client的請求。
4)主從同步能夠同來提升系統的可伸縮性,咱們能夠用多個slave專門處理client端的讀請求,也能夠用來作簡單的數據冗餘或者只在slave上進行持久化從而提高集羣的總體性能。
5)對於老版本的redis,每次重連都會從新發送全部數據

四、Redis主動同步設置方法

有兩種方式:

1)命令方式(臨時生效)

redis-cli slaveof no one              #中止主從同步
redis-cli slaveof 192.168.1.100 6379      #啓動主從同步

2)修改配置文件(永久)

1、修改配置文件
vim /data/6380/redis.conf
slaveof 192.168.0.135 6379                   #指定主master的IP和端口
masterauth yunjisuan                         #指定驗證的密碼
2、重啓redis的服務
redis-cli -p 6380 -a yunjisuan shutdown      #關閉6380redis進程
redis-server /data/6380/redis.conf &         #後臺啓動

當再次啓動從庫時出現以下信息:

 * Connecting to MASTER 192.168.0.135:6379                      #鏈接master
 * MASTER <-> SLAVE sync started                                #開始發送sync
 * Non blocking connect for SYNC fired the event.               #這是一個不阻塞事件
 * Master replied to PING, replication can continue...          #master應答了ping,同步開始
 * Partial resynchronization not possible (no cached master)    #從新進行同步不可能(master沒有緩存內容)
 * Full resync from master:                                     #從master同步所有數據 
 * MASTER <-> SLAVE sync: receiving 49 bytes from master        #從master接收到49字節數據
 * MASTER <-> SLAVE sync: Flushing old data                     #刷新舊數據
 * MASTER <-> SLAVE sync: Loading DB in memory                  #數據放到內存
 * MASTER <-> SLAVE sync: Finished with success                 #同步完成
 * Background append only file rewriting started by pid 3620    #AOF重寫
 * Background AOF rewrite terminated with success               #AOF重寫成功
* Background AOF rewrite finished successfully #AOF重寫完畢

redis主從同步測試

redis-cli -a yunjisuan -p 6380 get name                         #獲取redis6380的鍵name的值
redis-cli -a yunjisuan -p 6380 monitor                          #監聽主服務寫入操做
redis-cli -a yunjisuan -p 6379 set name xxxxx                   #向redis6379裏存一個key=name,value=tom的數據
redis-cli -a yunjisuan -p 6380 get name                         #獲取redis6380的鍵name的值

 redis主從同步相關配置參數解釋

slaveof 192.168.0.135 6379              #用於標識master的鏈接IP及端口號
masterauth yunjisuan                    #master端鏈接密碼
slave-serve-stale-data yes              #從庫鏈接不上主庫,設置yes,從庫依然正常提供服務,但內容有多是過時的。設置no,不提供服務,slave會應答一個錯誤提示
slave-read-only yes                     #從庫被設置爲只能讀
repl-ping-slave-period 10               #每10秒發送ping,到master端
repl-backlog-size 1mb                   #用於同步的backlog大小,用於從庫增量同步
repl-backlog-ttl 3600                   #當主從鏈接斷開,backlog的生存週期   
slave-priority 100                      #slave的優先級

 查看redis各項參數的方法

 redis-cli -a yunjisuan -p 6379         #登錄
127.0.0.1:6379> info                    #查看各項信息
127.0.0.1:6379> info cpu                #查看CPU信息
127.0.0.1:6379> info clients            #查看客戶端信息


127.0.0.1:6379> info replication #查看同步信息 role:master #本redis是主 connected_slaves:1 #鏈接從服務的數量 slave0:ip=192.168.0.135,port=6380,state=online,offset=11972,lag=1 #從庫ip,端口,狀態,偏移量等

6、redis的高級特性

一、redis的訂閱功能

pub/sub,發佈/訂閱是一種消息通訊模式,主要目的解耦消息發佈者和消息訂閱者之間的耦合,也解決二者在物理部署上的耦合,與設計模式中的觀察者模式相似;

redis可將數據推到某個信息管道中,其它人可經過訂閱這些管道來獲取推送過來的消息;

#開啓redis的訂閱功能(一個窗口)
127.0.0.1:6379> subscribe yunjisuan                         #開啓頻道名:yunjisuan的訂閱功能
127.0.0.1:6379> subscribe yunjisuan* #可開啓多個窗口進行訂閱 #對頻道進行內容推送 只要在推送端推送,訂閱端就能看到(同臺機器,另個窗口)
127.0.0.1:6379> publish yunjisuan 'welcome' #向頻道yunjisuan推送welcome (integer) 2 #推送成功的人數 127.0.0.1:6379> publish yunjisuan '很高興' 更多 help @pubsub

二、redis數據過時設置及過時機制

redis對過時key採用了lazy expiration,兩種方式:passive way(在訪問key時斷定key是否過時,若是過時則進行過時處理);active way(每秒對volatile keys進行抽樣測試,若是有過時key,將對全部過時key進行處理);

127.0.0.1:6379> expire name 5       #給key  name設置5秒過時時間
127.0.0.1:6379> TTL name            #查看key過時時間(-1爲永久不過時,-2爲已通過期)
127.0.0.1:6379> get name            #過時了的key是沒法經過key獲取value的
更多 help @generic

過時的key沒有被訪問可能不會被刪除

三、事務性

redis支持簡單的組合型的命令,例如以nx結尾的命令用於判斷key所對應的value沒有時也進行某個命令;

127.0.0.1:6379> setnx name        #當key的值不存在時,設置key的值
127.0.0.1:6379> set name tom      #設置一個key,值爲tom
127.0.0.1:6379> get name          #查看key的值
127.0.0.1:6379> multi             #開始提交事務
127.0.0.1:6379> set name a        #(當事務中有錯誤時將都不執行)
127.0.0.1:6379> set name b        #(當事務中有錯誤時將都不執行)
127.0.0.1:6379> exec              #(執行以上事務,discard爲取消事務)

 四、redis持久化

redis支持兩種持久化方式,一種是Snapshotting(快照)也是默認方式,另外一種是Append-only file(縮寫aof)的方式。

1)數據快照

將內存中數據以快照的方式寫入到二進制文件中,默認的文件名爲dump.rdb,若redis意外掛掉則會丟失最後一次快照的全部修改。

#與rdb相關的配置文件信息
dir /data/redis/               #dir爲rdb存儲的路徑
dbfilename dump.rdb            #rdb存儲文件的名字
save 900 1                     #900 秒內若是超過1個key被修改,則發起快照保存
save 300 10                    #300 秒內若是超過10個key被修改,則發起快照保存
save 60  10000                 #60 秒內若是超過10000個key被修改,則發起快照保存
rdbcompression no              #rdb壓縮最好關閉,影響cpu

快照保存過程:

a、redis調用fork,如今有了子進程和父進程 
b、父進程處理client請求,子進程將內存內容寫入到臨時文件。因爲Linux的寫時複製機制(copy on write)父子進程會共享相同的物理頁面,因此子進程的數據是fork時的一個快照。
c、當子進程將快照寫入臨時文件完畢後,用臨時文件替換原來的快照文件,而後子進程退出。

注:client能夠用save、bgsave命令通知redis作一次快照持久化。
save操做是在主線程中保存快照的,因爲redis是用一個主線程來處理全部client的請求,這種方式會阻塞全部client請求。因此不推薦使用。bgsave開啓一個子進程所以不會阻塞。
每次快照持久化都是將內存數據完整寫入到磁盤一次,並非增量的同步變動數據。若是數據量大,且寫操做比較多,會引發大量的磁盤io操做,會嚴重影響性能。 數據快照的原理是將整個Redis中存的全部數據一遍一遍的存到一個擴展名爲rdb的數據文件中。經過SAVE命令能夠調用這個過程。 redis關閉時,redis自動進行RDB文件的保存 啓動時會讀取RDB文件.若是沒有找到RDB文件則數據丟失.

設置開啓或者關閉rdb存儲

方法一:  修改配置文件
vim /usr/local/redis/conf/redis.conf
save ""                              #關閉rdb
save 60 10000                       #開啓rdb
save 300 10          
save 900 1 

方法二: 在線修改配置,不用重啓服務
redis-cli config set save ""          #關閉rdb存儲
redis-cli config rewrite              #配置保存
redis-cli config set save "180 1 120 10 60 10000"       #開啓rdb
redis-cli config rewrite              #配置保存    

進行有rdb文件的數據還原測試

redis-cli -a yunjisuan set names john             #向redis裏寫入一個鍵值對
redis-cli -a yunjisuan get names                  #查看鍵的值
ll --full-time /usr/local/redis/data/             #此時/usr/local/redis/data目錄下沒有任何東西
redis-cli -a yunjisuan shutdown #關閉redis進程
* Saving the final RDB snapshot before exiting. #關閉時,redis自動進行RDB文件的保存 * DB saved on disk #RDB文件已經保存到了磁盤上
ll --full-time /usr/local/redis/data/ #此時目錄下已經生成了RDB快照 redis-server /usr/local/redis/conf/redis.conf & #後臺啓動redis redis-cli -a yunjisuan get names #查詢redis中的鍵值對

2)Append-Only File(追加式的操做日誌)

redis會將收到的寫命令都經過write函數追加到文件中,默認是appendonly.aof,當redis重啓時會從新加載這個文件,用以在內存中重建整個DB;

相似MySQL的binlog日誌方式,記錄每次對DB有變化的操做

有三種方式以下(默認是:每秒fsync一次)
appendonly yes      #啓用aof持久化方式 no關閉 appendfsync always #收到寫命令就當即寫入磁盤,最慢,可是保證徹底的持久化 appendfsync everysec   #每秒鐘寫入磁盤一次,在性能和持久化方面作了很好的折中 appendfsync no      #徹底依賴os,性能最好,持久化沒保證

aof引起的問題

假如咱們調用incr test命令100次,文件中必須保存所有的100條命令,其實有99條都是多餘的,爲了壓縮aof的持久化文件。redis提供了bgrewriteaof命令,優化aof文件

開啓bgrewriteaof重寫的方式

1、命令測試
127.0.0.1:6379> set num 1                #設置一個key,值是1
127.0.0.1:6379> incr num                 #自動加1
127.0.0.1:6379> incr num              
cat   appendonly.aof                     #優化前,全部命令都保存
127.0.0.1:6379> bgrewriteaof             #啓動優化命令
cat   appendonly.aof                     #優化後,保存
2、修改配置文件,自動優化 449 appendonly yes #修改本行內容開啓AOF 520 auto-aof-rewrite-percentage 100 #當100%達到最小大小的時候纔會執行重寫 521 auto-aof-rewrite-min-size 64mb #自動重寫aof文件的最小大小

aof保存過程

一、redis調用fork,如今有父子兩個進程
二、子進程根據內存中的數據庫快照,往臨時文件中寫入重建數據庫狀態的命令。
三、父進程繼續處理client請求,除了把寫命令寫入到原來的aof文件中。同時把收到的寫命令緩存起來.這樣就能保證若是子進程重寫失敗的話並不會出問題。
四、當子進程把快照內容寫入已命令方式寫到臨時文件中後,子進程發信號通知父進程。而後父進程把緩存的寫命令也寫入到臨時文件。
五、如今父進程可使用臨時文件替換老的aof文件,並重命令名,後面收到的寫命令也開始往新的aof文件中追加。

重寫aof文件的操做:並無讀取舊的aof文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件

7、其餘

一、經常使用命令

flushdb                      #清空當前庫
flushall                     #清空全部庫
config get *                 #查看當前配置信息
config set appendonly yes    #在線修改
redis-benchmark -h localhost  -p 6379 -c 100 -n 10000     #100個併發,一萬次

二、內存優化

 redis hash在value內部是一個hash map,若該map的成員數較少,則會採用相似一堆線性緊湊格式來存儲該map,即省去了大量指針的內存開銷;

hash-max-zipmap-entries 64      #當value這個map內部不超過多少個成員時會採用線性緊湊技術,默認64,超過該值自動轉爲hash map方式;
hash-max-zipmap-value 512       #當value這個map內的每一個成員值長度不超過多少個byte就會採用線性緊湊格式存儲來節省空間;
list-max-ziplist-value 64 #list數據類型節點值大小小於多少字節會採用緊湊存儲格式
list-max-ziplist-entries 512 #list數據類型多少節點如下會採用去指針的緊湊存儲格式
set-max-intset-entries 512      #set數據類型內部數據若是所有是數值型,且包含多少節點如下會採用緊湊格式存儲
activerehashing yes        #是否激活重置哈希

redis優化總結:

一、根據業務須要選擇合適的數據類型,併爲不一樣的應用場景設置相應的緊湊存儲參數;

二、當業務場景不須要數據持久化時,關閉全部的持久化方式可得到最佳的性能和最大的內存使用量;

三、若須要使用持久化,根據是否能夠容忍重啓後丟失部分數據,在snapshot和aof,這二者中選其一,不要使用虛擬內存vm及disk store方式(diskstore已obsolete),每秒實時寫入AOF文件

四、儘可能不要讓redis超過佔總內存的60%;

五、redis.conf中maxmemory,是告訴redis當使用了多少物理內存後就開始拒絕後續的寫入請求,該參數能很好的保護redis不會由於使用了過多的物理內存而致使swap,最終嚴重影響性能開始不穩定甚至崩潰;vm-enabled設置爲no

六、大數據量儘可能按業務使用多個redis instance把數據分散開

相關文章
相關標籤/搜索