Redis詳解

1、Redis安裝html

2、Redis命令node

3、StackExchange.Redispython

4、四大結構體git

5、Redis數據結構之Stringgithub

6、Redis數據結構之Listweb

7、Redis數據結構之Hash表redis

8、Redis數據結構之Set算法

9、Redis數據結構之sorted_setsql

10、Redis數據結構之hyperloglog數據庫

11、Transactions

12、發佈/訂閱

十3、redis驅動批量執行命令

十4、Redis使用Lua

十5、Redis兩種持久化方式

十6、搭建Redis主-備(mster-slave)

十7、搭建Redis主-備(mster-slave)+哨兵(sentinel)

十8、 web監控【redislive】

十9、 搭建cluster(集羣) 

redis中文文檔:http://www.redis.cn/

redis可視化工具:https://raw.githubusercontent.com/caoxinyu/RedisClient/windows/release/redisclient-win32.x86.2.0.exe

1、Redis安裝

1,Windows安裝

①下載redis並安裝msi文件

https://github.com/MicrosoftArchive/redis

 

②設置環境變量

 

③運行server

redis-server D:\Redis\redis.windows-service.conf

④運行client

redis-cli

 

2,Linux安裝

①進入usr-》local目錄下

②$ wget http://download.redis.io/releases/redis-4.0.6.tar.gz   下載redis

③$ tar xzf redis-4.0.6.tar.gz  解壓

④$ cd redis-4.0.6  進入目錄

⑤$ make  編譯

⑥編譯好以後進入src文件下,發現編譯好了幾個可執行文件。將這幾個文件考到sbin下面

⑦配置環境變量

/etc/profile 打開文件,設置

export PATH=$PATH:/usr/local/redis-4.0.6/sbin

⑧重啓centOS 

 

2、Redis命令

set username jack 設置緩存

get username 讀取緩存

keys * 查看全部的key

flushall 清空全部數據(沒有一點安全保證)

bgsave 立馬持久化緩存信息

bind 127.0.0.1  若是沒有註銷掉bind,則Redis監聽全部連接

protected-mode yes【yes只能迴路地址127.0.0.1 本地訪問】

生產環境通常配置
#bind
protected-mode no

port 6379 配置redis端口

dir ./ 配置rdb和logfile的存放位置(例如:dir /usr/redis/sbin/db)

databases 16設置數據庫的數量

logfile "server_log.txt" 指定日誌文件名稱

loglevel notice 日誌記錄級別

rename-command 改變命令的名稱

redis-cli -h 192.168.1.102 -p 6379 遠程連接redis

redis-cli -h 192.168.1.102 -p 6379 -a 123456 --stat 監控redis狀態

設置密碼:

在配置文件中設置requirepass(例如 requirepass 123456)
鏈接redis服務器時須要帶上密碼(例如:redis-cli -h 192.168.1.102 -p 6379 -a 123456
redis遠程連接失敗總結
①看看redis-server指向的配置文件是否指定對了
②conf配置
#bind
protected-mode no
③關閉centOS的防火牆
systemctl stop firewalld.service #中止firewall
systemctl disable firewalld.service #禁止firewall開機啓動

1,設置key的過時時間
persist【O(1)】:PERSIST key【移除給定key的生存時間】
expire【O(1)】:EXPIRE key seconds【設置key的過時時間,單位秒】
pexpire【O(1)】:PEXPIRE key milliseconds【設置key的過時時間,單位毫秒】
expireat【O(1)】:EXPIREAT key timestamp【設置key的過時時間,單位時間戳】

2,Redis配置

①maxmemory設置最大內存空間(默認註釋)

 

②maxmemory-policy最大內存空間策略(默認註釋)

策略:

# volatile-lru -> 刪除使用LRU算法設置過時的key
# allkeys-lru ->根據LRU算法刪除任何key
# volatile-random -> 刪除過時集合的key
# allkeys-random ->刪除一個隨機key,任何key
# volatile-ttl ->刪除最接近過時時間的key
# noeviction -> 若是內存寫滿,則拋異常

lru :最久未使用的 

 

 

3、StackExchange.Redis

wireshark 網絡封包分析軟件

nuget StackExchange.Redis

public static class RedisCache
    {
        private static ConnectionMultiplexer connection;
        private static IDatabase database;

        static RedisCache()
        {
            var options=new ConfigurationOptions()
            {
                Password = "123456",
                EndPoints = { { "192.168.1.101", 6379 } }
            };
            connection = ConnectionMultiplexer.Connect(options);
            database = connection.GetDatabase();
        }
        public static void Set(string key,string str)
        {
            database.StringSet(key, str);
        }
        public static string Get(string key)
        {
           return database.StringGet(key);
        }
    }
RedisCache

https://stackexchange.github.io/StackExchange.Redis/Configuration

 

4、四大結構體

1,RedisServer struct

2,RedisDb struct 標識一個db,config配置默認爲16個RedisDb 

3,RedisObject struct 也就是對象化的數據結構表示

4,SDS struct char[] 一個包裝類(存放字符串)

 

5、Redis數據結構之String

1,get/set 命令(時間複雜度O(1))

SET key value [EX seconds] [PX milliseconds] [NX|XX]

  • EX seconds – 設置鍵key的過時時間,單位時秒
  • PX milliseconds – 設置鍵key的過時時間,單位時毫秒
  • NX – 只有鍵key不存在的時候纔會設置key的值
  • XX – 只有鍵key存在的時候纔會設置key的值
案例:使用分佈式鎖
set a a NX
業務操做
del a

2,incr/decr/incrby/decrby

incr 自增長1(i++)

decr自增減1(i--)

incrby自增長n(i=i+n)

decrby自增減n(i=i-n)

若是存放string中的value是int,則內存使用int存儲值

3,ttl key 查詢key還有多長時間過時(-2 表示過時)

4,PSETEX/SETEX 

PSETEX key milliseconds value
SETEX key seconds value
PSETEX和SETEX同樣,惟一的區別是到期時間以毫秒爲單位,而不是秒。

 

6、Redis數據結構之List

雙向鏈表

能夠用做隊列(lpush/rpop、rpush/lpop)或者棧(lpush/lpop、rpush/rpop)

通常用做隊列

 

lpush:LPUSH key value [value ...]【將全部指定的值插入到存於 key 的列表的頭部。若是 key 不存在,那麼在進行 push 操做前會建立一個空列表】

lpop:LPOP key【移除而且返回 key 對應的 list 的第一個元素】

rpush:RPUSH key value [value ...]【向存於 key 的列表的尾部插入全部指定的值。若是 key 不存在,那麼會建立一個空的列表而後再進行 push 操做】

rpop:RPOP key【移除並返回存於 key 的 list 的最後一個元素】

llen:LLEN key【返回存儲在 key 裏的list的長度。 若是 key 不存在,那麼就被看做是空list,而且返回長度爲 0】

blpop:BLPOP key [key ...] timeout【彈出最前面的值,若是列表中沒有值,會阻塞】
brpop:BRPOP key [key ...] timeout【彈出最後面的值,若是列表中沒有值,會阻塞】
注:timeout:等待時間,單位秒。0:標識永久等待
lrange:LRANGE key start stop【返回存儲在 key 的列表裏指定範圍內的元素】
注:start stop位數組的下標

linsert:LINSERT key BEFORE|AFTER pivot value【把 value 插入存於 key 的列表中在基準值 pivot 的前面或後面】
注:BEFORE爲以前/AFTER爲以後
pivot:list中的值

 

7、Redis數據結構之Hash表

hget:HGET key field【返回 key 指定的哈希集中該字段所關聯的值】
hset:HSET key field value
設置 key 指定的哈希集中指定字段的值。
若是 key 指定的哈希集不存在,會建立一個新的哈希集並與 key 關聯。
若是字段在哈希集中存在,它將被重寫。
field:字典中的key
value:字典中的value

hdel:HDEL key field [field ...]【從 key 指定的哈希集中移除指定的域】
hexists:HEXISTS key field【返回hash裏面field是否存在】
hgetall:HGETALL key【返回 key 指定的哈希集中全部的字段和值】
hkeys:HKEYS key【返回 key 指定的哈希集中全部字段的名字】
hlen:HLEN key【返回 key 指定的哈希集包含的字段的數量】
hmget:HMGET key field [field ...]【返回 key 指定的哈希集中指定字段的值】
hmset:HMSET key field value [field value ...]【設置 key 指定的哈希集中指定字段的值】
hvals:HVALS key【返回 key 指定的哈希集中全部字段的值】

 

8、Redis數據結構之Set

無value的字典

sadd【O(N)】:SADD key member [member ...]【添加一個或多個指定的member元素到集合的 key中】
scard【O(1)】:SCARD key【返回集合存儲的key的基數 (集合元素的數量)】
sismember【O(1)】:SISMEMBER key member【檢查成員member是否存在集合中】
smembers【O(N)】:SMEMBERS key【返回key集合全部的元素】
spop【O(1)】:SPOP key [count]【隨機從集合彈出count(默認1)個值】
srem【O(N)】:SREM key member [member ...]【在key集合中移除指定的元素】

差集、交集、並集
sdiff【O(N)】:SDIFF key [key ...]【差集】
sdiffstore【O(N)】:SDIFFSTORE destination key [key ...]【將差集保存到destination中】
sinter【O(N*M)】:SINTER key [key ...]【交集】
sinterstore【O(N*M)】:SINTERSTORE destination key [key ...]【將交集保存到destination中】
sunion【O(N)】:SUNION key [key ...]【並集】
sunionstore【O(N)】:SUNIONSTORE destination key [key ...]【將並集保存到destination中】

 

9、Redis數據結構之sorted_set

通常用作優先級隊列

zadd【O(log(N))】:ZADD key [NX|XX] [CH] [INCR] score member [score member ...]【將全部指定成員添加到鍵爲key有序集合(sorted set)裏面】
XX: 僅僅更新存在的成員,不添加新成員。
NX: 不更新存在的成員。只添加新成員。
CH: 修改返回值爲發生變化的成員總數,原始是返回新添加成員的總數 (CH 是 changed 的意思)。更改的元素是新添加的成員,已經存在的成員更新分數。 因此在命令中指定的成員有相同的分數將不被計算在內。注:在一般狀況下,ZADD返回值只計算新添加成員的數量。
INCR: 當ZADD指定這個選項時,成員的操做就等同ZINCRBY命令,對成員的分數進行遞增操做。
zcard【O(1)】:ZCARD key【返回key的有序集元素個數】
zrange【O(log(N)+M)】:ZRANGE key start stop [WITHSCORES]【從小到大排序。顯示字典信息(WITHSCORES 顯示出key)】【例如:zrange sdic 0 -1 withscores】
zrevrange【O(log(N)+M)】:ZREVRANGE key start stop [WITHSCORES]【從大到小排序。顯示字典信息(WITHSCORES 顯示出key)】【例如:zrevrange sdic 0 -1 withscores】
zremrangebyrank【O(log(N)+M)】:ZREMRANGEBYRANK key start stop【移除有序集key中】
0:最小
-1:最大
-2:第二大。。以此類推

 

10、Redis數據結構之hyperloglog

等於distinct+count
計算不是100%準確
使用場景:計算某一天獨立ip訪問數量
pfadd 20180125 192.168.1.1 192.168.1.1 192.168.1.2【O(1)】
pfcount 20180125【O(1)】

11、Transactions

multi:開啓一個事務
exec:提交事務
discard:回滾事務

watch【樂觀鎖】:WATCH key [key ...]

例如客戶端1watch username並開啓了一個事務。當在另外一個客戶端2修改了username值的時候。客戶端1事務exec會執行失敗(回滾)

 

12、發佈/訂閱

subscribe:SUBSCRIBE channel [channel ...]【訂閱頻道】
publish:PUBLISH channel message【發佈消息】

 psubscribe:PSUBSCRIBE pattern [pattern ...]【訂閱給定的模式的頻道】

 

十3、redis驅動批量執行命令

        static void Main(string[] args)
        {
            var con= ConnectionMultiplexer.Connect("192.168.1.102:6379");
            var db = con.GetDatabase();

            var batch= db.CreateBatch();

            batch.SetAddAsync("username", "hunter");
            batch.ListInsertBeforeAsync("list", "1", "2");
            batch.HashSetAsync("dic", "username", "jack");
            batch.Execute();
            Console.ReadKey();
        }

 

十4、Redis使用Lua

Lua工具下載地址:LuaForWindows_v5.1.4-46.exe

1,命令
EVAL script numkeys key [key ...] arg [arg ...]
script:指定lua腳本的路徑。或者直接寫lua腳本
numkeys:制定參數的個數
key:在腳本中使用到的key(KEYS 全局key集合。單項:KEYS[1])
arg:在腳本中使用到的arg(ARGV 全局arg集合。單項:ARGV[1])
注:KEYS[0]或者ARGV[0]是錯誤的寫法

2,Lua腳本調用Redis
redis.call('set','foo','bar')
redis.pcall('hset','dic','key','value')
redis.call() 與 redis.pcall()很相似, 他們惟一的區別是當redis命令執行結果返回錯誤時,
redis.call()將返回給調用者一個錯誤,而redis.pcall()會將捕獲的錯誤以Lua表的形式返回

3,案例
①直接嵌入lua腳本

> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"

②調用獨立的lua腳本

return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}
lua文件
redis-cli --eval C:\Users\Hunter2\Desktop\Lua\text.lua a b , a b
1) "key1"
2) "key2"
3) "first"
4) "second"

③更高級的調用

需求:輸入的參數在集合中存在,則打印出來

local key=KEYS[1]
local args=ARGV

local result={}
local list=redis.call("smembers",key)
for m,n in ipairs(args) do
    local exists= redis.call("sismember",key,n)
    if(exists==1)then
    table.insert(result,n)
    end
end
return result
Lua文件
C:\WINDOWS\system32>redis-cli --eval C:\Users\Hunter2\Desktop\Lua\text.lua list , 1 2 3 10
1) "1"
2) "2"
3) "3"

注:逗號分割key和agrv 

 

十5、Redis兩種持久化方式

1,rds(默認)
快照模式,定時保存。若是重啓有可能會丟失部分數據

配置信息:

強制持久化命令:save(客戶端阻塞)或者bgsave(會開啓一個進程執行)

2,aof

來一條命令則保存一次,aof文件保存的是文本協議

開啓方式 

①註銷save

②appendonly設置爲yes

 

三種寫入模式:

#appendfsync always:來一條保存一條,強制保存到硬盤【安全性高,性能差】
appendfsync everysec:1秒強制保存到硬盤一次【折中方案】
#appendfsync no:來一條保存一條,只保存到系統的緩衝期,至於保存到硬盤是有系統決定【安全性差,性能高】

 

十6、搭建Redis主-備(mster-slave)

1,配置mster-slave
配置文件# slaveof <masterip> <masterport>配置主機地址
例如:slaveof 192.168.1.102 6379
若是主redis有密碼須要配置# masterauth <master-password>
info 查看redis信息

注:一旦redis服務器被設置爲slave,則該redis不能寫入了。只能從master中寫入

2,c#中使用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var con= ConnectionMultiplexer.Connect("192.168.1.102:6379,192.168.1.103:6379");
            var db = con.GetDatabase();

            db.StringAppendAsync("password", "123456");//會使用主redis
            var p = db.StringGetAsync("password").Result;//會使用備redis

            Console.WriteLine(p);
            Console.ReadKey();
        }
    }
}
c#端調用

注:若是主redis掛了,則寫入會失敗。能夠查詢

 

十7、搭建Redis主-備(mster-slave)+哨兵(sentinel)

sentinel監視redis主備,當主redis掛了,sentinel自動讓一個slave變爲master。
當原來master恢復以後,原來master恢復已經成爲slave了

1,架構sentinel

例如在一臺centos上創建三個哨兵

這三個哨兵會監視一個master,當有2個哨兵主觀認爲master掛了,則sentinel自動讓一個slave變爲master

主redis:192.168.1.102:6379

備redis:192.168.1.103:6379

主redis未掛時,備redis的狀態:

主redis掛了,備redis的狀態:

sentinel案例下載:https://pan.baidu.com/s/1ggvCu47

1,配置具體的sentinel

①拷貝redis-sentinel程序和sentinel.conf配置文件到s一、s二、s3文件中

②配置sentinel.conf

port 26379  #設置sentinel的端口

protected-mode no #將protected-mode設置爲no

sentinel monitor <master-name> <ip> <redis-port> <quorum> #設置監控的master

master-name:設置主redis 的名稱,隨便寫

ip:主redis 的ip地址

redis-port:主redis的端口號

quorum:當主觀認爲master掛掉的哨兵達到2個時,則客觀認爲master掛了。須要切換master了

例:sentinel monitor mymaster 192.168.1.102 6379 2

sentinel auth-pass <master-name> <password> #若是master設置了密碼,則須要配置master的密碼

例:sentinel auth-pass mymaster 123456

sentinel down-after-milliseconds mymaster 30000 #master30秒沒響應,則主觀認爲master掛了

③啓動sentinel

進入放置sentinel的文件夾

執行命令./redis-sentinel ./sentinel.conf 啓動sentinel

注意:在同一系統下運行多個sentinel,sentinel的端口號不要重複

 

十8、 web監控【redislive】

python寫的一個web監控

1,安裝redislive

①首先須要安裝pip(python的安裝工具包pip-9.0.1.tar.gz)【至關於nuget】
下載地址:https://pypi.python.org/pypi/pip

網速慢能夠下載:https://pan.baidu.com/s/1qZezffm

拷貝到centos的usr文件下,解壓,進入解壓文件中
python setup.py install 安裝

②安裝tornado【至關於iis】
pip install tornado --upgrade

③安裝redis.py 【python redis驅動,至關於.net StackExchange】
pip install redis

④安裝python-dateutil 【類庫,至關於dll】
pip install python-dateutil --upgrade 強制更新到最新

⑤獲取redislive的源代碼
https://github.com/nkrode/RedisLive
解壓放到centos的usr文件下。進入文件夾
將redis-live.conf.example改成redis-live.conf

redis-live.conf配置文件解析:
RedisServers:監控的RedisServers的服務器地址和端口
DataStoreType:存儲類型(redis或者Sqlite存儲,默認redis)
RedisStatsServer:配置存儲redis的服務器地址和端口
{
    "RedisServers":
    [ 
        {
              "server": "192.168.1.103",
              "port" : 6379
        }        
    ],

    "DataStoreType" : "redis",

    "RedisStatsServer":
    {
        "server" : "192.168.1.103",
        "port" : 6379
    },
    
    "SqliteStatsStore" :
    {
        "path":  "to your sql lite file"
    }
}
配置案例

⑥開啓監控腳本:./redis-monitor.py --duration=120【duration=120 默認採集二分鐘】

⑦開啓web站點:./redis-live.py

⑧訪問
http://localhost:8888/index.html
http://192.168.1.103:8888/index.html

 

十9、 搭建cluster(集羣)

參考文檔:http://www.redis.cn/topics/cluster-tutorial.html

可能出現各類依賴問題請參考:
http://www.javashuo.com/article/p-cbdmvsiu-ko.html
http://blog.csdn.net/Hello_World_QWP/article/details/78260684
http://blog.csdn.net/hello_world_qwp/article/details/78261618

1,開啓cluster(集羣)模式
配置文件:
cluster-enabled yes 開啓集羣
cluster-config-file nodes-6379.conf 集羣節點文件

2,redis src下找到redis-trib.rb
①安裝ruby環境:yum install ruby

②ruby的redis驅動:gem install redis
③rubygems安裝:yum install -y rubygems

④經過第三方工具進行安裝
./redis-trib.rb create --replicas 1 192.168.1.103:6379 192.168.1.103:6380 192.168.1.103:6381 192.168.1.103:6382

cluster nodes 查看集羣
redis-cli -c 使用這種redis-cli的開啓方式

3,c#驅動訪問方式:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var con= ConnectionMultiplexer.Connect("192.168.1.103:6379,192.168.1.103:6380,192.168.1.103:6381,192.168.1.103:6382");
            var db = con.GetDatabase();

            db.StringSet("cc", "123456");//會使用主redis
            var p = db.StringGetAsync("cc").Result;//會使用備redis

            Console.WriteLine(p);
            Console.ReadKey();
        }
    }
}
View Code

升級完ruby須要重啓

注意:

>>>建立羣集
***錯誤:集羣建立的配置無效。
*** Redis羣集至少須要3個主節點。
***對於每一個節點3個節點和1個副本,這是不可能的。
***至少須要6個節點。

相關文章
相關標籤/搜索