django - 總結 - redis緩存

8、redis 補充- 操做 - 增刪改查

對字典,從新設計結構,增刪改查。html

hmset  keys  hget   scan_iter  hgetall python

import redis
import json

conn = redis.Redis(host='140.143.227.206',port=6379,password='1234')
"""
-----> 初版
{
    luffy_shopping_car:{
        6:{
            11:{
                'title':'21天入門到放棄',
                'src':'xxx.png'
            },
            12:{
                'title':'21天入門到放棄',
                'src':'xxx.png'
            }
        }
    }
}
-----> 第二版
{
    luffy_shopping_car_6_11:{
        'title':'21天入門到放棄',
         'src':'xxx.png'
    },
    luffy_shopping_car_6_12:{
        'title':'21天入門到放棄',
         'src':'xxx.png'
    },
    luffy_shopping_car_6_14:{
        'title':'21天入門到放棄',
         'src':'xxx.png'
    }
}
"""
# conn.flushall()

# 添加課程
# redis_key = "luffy_shopping_car_%s_%s" %(7,12,)
# conn.hmset(redis_key,{'title':'21天入門到放棄','src':'xxx.png'})

# 刪除課程
# conn.delete('luffy_shopping_car_6_12')
# print(conn.keys())

# 修改課程
# conn.hset('luffy_shopping_car_6_11','src','x1.png')
# print(conn.hget('luffy_shopping_car_6_11','src'))

# 查看全部課程
# print(conn.keys("luffy_shopping_car_6_*"))
# for item in conn.scan_iter('luffy_shopping_car_6_*',count=10):
#     course = conn.hgetall(item)
#     print(course)

# conn.set('k1',123)
# print(conn.type('luffy_shopping_car_6_11'))
# print(conn.type('k1'))

from django.core.cache import cache



# print(conn.keys())
#
# for key in conn.scan_iter("luffy_shopping_car_1*"):
#
#     title = conn.hget(key,'title')
#     img = conn.hget(key, 'img')
#     policy = conn.hget(key, 'policy')
#     default_policy = conn.hget(key, 'default_policy')
#
#
#     print(str(title,encoding='utf-8'))
#     print(str(img,encoding='utf-8'))
#     print(json.loads(str(policy,encoding='utf-8')))
#     print(str(default_policy,encoding='utf-8'))




print(conn.keys())
conn.scan_iter()

print(conn.exists('luffy_sg_car_1_1'))

 

9、redis 補充 - 分佈式、高可用、讀寫分離

redis 
http://www.cnblogs.com/wupeiqi/articles/9348938.html
1. redis是什麼?
    是一個由C語言編寫的對內存進行存取數據的軟件(NoSQL數據庫;非關係型數據庫);

2. redis是單進程單線程的。

3. redis基礎:
    - 5大數據類型;
        - 字符串 
        - 列表 
        - 字典
        - 集合 
        - 有序結合
    - 發佈和訂閱
    - 事務 

4. 主從 = 高可用 = HA
    
    服務器A:10.211.55.19
        redis-server  /etc/redis-6379.conf  # 內部bind:0.0.0.0 port: 6379
    服務器B: 10.211.55.20
        redis-server  /etc/redis-6379.conf  # 內部bind:0.0.0.0 port: 6379 slaveof: 10.211.55.19
    
        
    特殊狀況來了:若是主宕機,應該講從切換成主;
        手動:
            - 登陸redis將從變成主
            - 修改代碼,將鏈接字符串IP改爲10.211.55.20
        自動:
            - keepalived,監聽服務器的狀態作高可用;第三方組件;
            - sentinel(哨兵),檢測redis主服務器的狀態並將全部的slave獲取到,一旦主掛掉,則當即將從切換成主;
                redis-sentinel /etc/redis-sentinel-26379.conf(主IP,失敗個數)
                redis-sentinel /etc/redis-sentinel-26380.conf
                redis-sentinel /etc/redis-sentinel-26381.conf
                
                Python操做:
                    from redis.sentinel import Sentinel
                     
                    # 鏈接哨兵服務器(主機名也能夠用域名)
                    sentinel = Sentinel([('10.211.55.20', 26379)],socket_timeout=0.5)
                     
                    # # 獲取主服務器地址
                    # master = sentinel.discover_master('mymaster')
                    # print(master)
                    #
                    # # # 獲取從服務器地址
                    # slave = sentinel.discover_slaves('mymaster')
                    # print(slave)
                    #
                    #
                    # # # 獲取主服務器進行寫入
                    # master = sentinel.master_for('mymaster')
                    # master.set('foo', 'bar')
                     
                     
                    # # # # 獲取從服務器進行讀取(默認是round-roubin)
                    # slave = sentinel.slave_for('mymaster', password='redis_auth_pass')
                    # r_ret = slave.get('foo')
                    # print(r_ret)
                
    
    總結:
        - 高可用
        - 讀寫分離

5. 集羣=分佈式 
    如何實現分佈式集羣:
        - codis,國產 豌豆莢 開源;
        - twemproxy,twitter開源
        - cluster,redis官方提供
    
    redis的cluster的原理?
        16384槽位
        
        服務器A: 0-5000
        服務器B: 5001-10000
        服務器B: 10001 - 16384 
        
    Python操做redis cluester:
        redis-py-cluster模塊

6. 分佈式鎖 redlock算法
    dlm = Redlock([{"host": "localhost", "port": 6379, "db": 0}, ])
    # 若是 my_lock有值,則表示獲取鎖了
    # 若是 my_lock無值,則表示未獲取鎖,別人獲取走了。
    my_lock = dlm.lock("my_resource_name",1000)
    dlm.unlock(my_lock) # 刪除時調用lru腳本
    
    redis分佈式鎖實現原理:
        1. 配置全部要鏈接的服務器並計算服務器一半的個數;
        
        2. 獲取鎖:
                - 傳入參數:key,內部生成隨機字符串,超時時間
                
                - 循環全部服務器,在服務器上設置:
                    SET key 隨機字符串 NX PX 超時時間  # 若是已經存在則不設置
                
                - 設置成功的個數 >= 一半+1 且 花費時間小於超時時間
                
        3. 釋放鎖
            - 刪除key和value(內部調用lru腳本)
            - 超時釋放
        
7. 其餘:
    - 持久化:
        - AOF,記錄全部命令;
        - RDB,指定時間間隔作快照;
    - 過時策略 
        voltile-lru:從已設置過時時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰

        volatile-ttl:從已設置過時時間的數據集(server.db[i].expires)中挑選將要過時的數據淘汰

        volatile-random:從已設置過時時間的數據集(server.db[i].expires)中任意選擇數據淘汰

        allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰

        allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰

        no-enviction(驅逐):禁止驅逐數據
    - 不要是直接使用:
        - key
        - all  
        必定要使用scan_iter     
 

10、redis 補充 - 應用

http://www.cnblogs.com/wupeiqi/articles/5132791.htmlgit

redis是一個key-value存儲系統。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,redis支持各類不一樣方式的排序。與memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。github

  View Code
  實現計數器

五、發佈訂閱redis

發佈者:服務器算法

訂閱者:Dashboad和數據處理數據庫

Demo以下:django

  RedisHelper

訂閱者:json

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
from  monitor.RedisHelper  import  RedisHelper
 
obj  =  RedisHelper()
redis_sub  =  obj.subscribe()
 
while  True :
     msg =  redis_sub.parse_response()
     print  msg

發佈者:緩存

1
2
3
4
5
6
7
#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
from  monitor.RedisHelper  import  RedisHelper
 
obj  =  RedisHelper()
obj.public( 'hello' )

6. sentinel

redis重的sentinel主要用於在redis主從複製中,若是master顧上,則自動將slave替換成master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
from  redis.sentinel  import  Sentinel
 
# 鏈接哨兵服務器(主機名也能夠用域名)
sentinel  =  Sentinel([( '10.211.55.20' 26379 ),
                      ( '10.211.55.20' 26380 ),
                      ],
                     socket_timeout = 0.5 )
 
# # 獲取主服務器地址
# master = sentinel.discover_master('mymaster')
# print(master)
#
# # # 獲取從服務器地址
# slave = sentinel.discover_slaves('mymaster')
# print(slave)
#
#
# # # 獲取主服務器進行寫入
# master = sentinel.master_for('mymaster')
# master.set('foo', 'bar')
 
 
 
# # # # 獲取從服務器進行讀取(默認是round-roubin)
# slave = sentinel.slave_for('mymaster', password='redis_auth_pass')
# r_ret = slave.get('foo')
# print(r_ret)

  

更多參見:https://github.com/andymccurdy/redis-py/

http://doc.redisfans.com/

相關文章
相關標籤/搜索