採用多臺redis服務器,共同維護一整塊內存空間大小,最終實現了內存數據的擴容.node
1.在redis的根目錄中建立shards文件夾 mkdir shardsredis
2.將redis.conf文件複製3分到shards中 cp redis.conf shards算法
3.修改端口號 vim redis.confspring
4.啓動3臺redis vim
1.Hash一致算法介紹安全
1)肯定節點node的位置.服務器
2)對key進行hash運算.獲取惟一的位置app
3)以後順時針找到最近的節點.dom
4)以後連接節點進行set/get操做.異步
2.均衡性
爲了解決數據分配不均,採用虛擬節點的方式實現數據的均衡(均衡性算法)
3.單調性
當節點新增時,數據能夠實現自動的遷移.
重點:一旦節點宕機,則內存缺失.整個分片不能正常使用.
原則:若是節點新增,則儘量保證原有的數據不發生變化.
4.分散性
因爲分佈式的部署致使某些服務器不能使用所有的內存空間,同一個key有多個位置
5.負載
因爲分佈式的部署致使某些服務器不能使用所有的內存空間.同一個位置可能會有多個key
防止:儘量使用所有的內存空間.可以有效的下降分散性和負載.
1.編輯properties配置文件
#redis分片寫法
redis.nodes=192.168.175.129:6379,192.168.175.129:6380,192.168.175.129:6381
2.編輯配置類
/**
* 實現spring容器管理redis配置類
* @author Administrator
*
*/
@Configuration //標識配置類
@PropertySource("classpath:/properties/redis.properties") public class RedisConfig { @Value("${redis.nodes}") private String nodes; //node,node,node /** * redis分片
*/ @Bean @Scope("prototype") public ShardedJedis shardedJedis() { List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); String[] redisNodes = nodes.split(","); for (String redisNode : redisNodes) { //redisNode=IP:PORT String[] hostAndPort = redisNode.split(":"); String host = hostAndPort[0]; int port = Integer.parseInt(hostAndPort[1]); JedisShardInfo info = new JedisShardInfo(host, port); shards.add(info); } return new ShardedJedis(shards); } }
3.編輯切面信息
@Component //將類交給容器管理
@Aspect //標識切面
public class CacheAspect {
@Autowired
//private Jedis jedis;
private SharedJedis jedis; //若是是環繞通知,則參數必須寫ProceedingJoinPoint,必須位於第一位 @Around("@annotation(cacheFind)") ............
Redis會根據配置文件的規則,按期將內存中的數據持久化到磁盤中.當redis從新啓動時,會根據配置文件.實現內存數據的恢復
1、RDB模式
RDB模式是redis默認的持久化策略.
1.特色:
1).RDB模式按期實現數據的持久化 (可能會丟失數據)
2).RDB模式記錄的是內存數據的快照.持久化文件較小.
3).RDB模式在進行持久化操做時是阻塞的.(數據安全性考慮)
4).通常使用持久化的策略RDB的效率是最高的.建議使用.
2.save指令(save、bgsave)
能夠經過客戶端執行save指令.實現內存數據的持久化操做
bgsave表示後臺運行,異步操做.
save表示如今當即執行.表示同步操做.會形成線程阻塞.
3.持久化配置名稱
4.RBD持久化策略
save 900 1 若是用戶在900秒內,執行1次更新操做時,則持久化一次
save 300 10 在300秒內,執行10次更新操做時,則持久化
save 60 10000在60秒內,執行10000次更新操做時,則持久化
save 1 1 效率極低.
2、 AOF模式
AOF模式默認是關閉的.若是使用須要開啓.AOF模式最的是數據的追加.因此持久化文件較大.
1.特色:
1).AOF模式默認是關閉的.
2).AOF模式持久化時記錄用戶的操做過程,以後追加到持久化文件中.
3).AOF模式能夠實現實時備份.保證數據安全.
4).AOF模式效率低於RDB模式
5).AOF持久化文件須要按期維護.
6).AOF模式是異步的不會陷入阻塞
2.AOF持久化策略
appendfsync always 用戶作一次操做,持久化一次
appendfsync everysec 每秒持久化一次(默認)
appendfsync no 由操做系統決定什麼時候持久化. 通常不用
Redis中本身有內存優化策略.可以保證在內存數據即將達到上限時,可以實現自動的優化. 可是該策略默認是關閉的.
1.LRU算法
LRU是Least Recently Used的縮寫,即最近最少使用,是一種經常使用的頁面內置算法,選擇最近最久未使用的頁面予以淘汰。該算法賦予每一個頁面一個訪問字段,用來記錄一個頁面
自上次被訪問以來所經歷的時間 t,當須淘汰一個頁面時,選擇現有頁面中其 t 值最大的,即最近最少使用的頁面予以淘汰。
2.LFU算法
LFU(least frequently used (LFU) page-replacement algorithm)。即最不常用頁置換算法,要求在頁置換時置換引用計數最小的頁,由於常用的頁應該有一個較大的引用
次數。可是有些頁在開始時使用次數不少,但之後就再也不使用,這類頁將會長時間留在內存中,所以能夠將引用計數寄存器定時右移一位,造成指數衰減的平均使用次數。
3.內存優化算法
1).volatile-lru 設定超時時間的數據採用lru算法進行刪除
2).allkeys-lru 全部數據採用LRU算法進行刪除.
LFU redis5.0版本之後的算法.
3).volatile-lfu 設定超時時間的數據,採用lfu算法
4).allkeys-lfu 全部數據採用lfu算法.
5).volatile-random 設定超時時間的隨機算法
6).allkeys-random 全部數據的隨機算法
7).volatile-ttl 設定超時時間的數據按照可存活時間排序刪除
8).noeviction 默認設定 若是內存滿了不會刪除數據,而是報錯返回,有使用這自行決定.
4.修改內存
redis分片實現了內存數據的擴容.可是redis分片沒有實現高可用的效果.當redis分片的節點node若是宕機.致使整個分片不能正常執行.可否實現redis節點的高可用.
1.redis主從複製
1.1複製目錄
將redis根目錄中的shards目錄複製爲sentinel cp -r shards sentinel
1.2檢查節點狀態
默認狀態下,redis節點都是主機
1.3主從配置
注意:一旦實現主從結構以後,從機將不能set操做
1.4主從結構測試
1)在主機客戶端使用 info replication 命令
2)向redis主機中set數據,以後檢查從機中是否實現數據同步
1.5.redis哨兵實現
實現步驟:
1)哨兵啓動時首先監控主機的狀態,而且記錄主機的所有信息(包括從機的host:port);
2)當主機發生宕機現象時.首先會根據PING-PONG心跳檢測機制,查看主機的狀態,若是連續3次主機沒法響應,則判定主機宕機.
3)由哨兵利用本身的推選的算法.選舉出新的主機.而且將其餘的節點改成當前主機的從機.
1.6 編輯哨兵配製文件
1)將哨兵的配置文件複製到sentinel目錄中.
2)關閉哨兵保護模式
3)開啓後臺啓動
4)修改哨兵監控信息
mymaster:變量名稱 標識主機信息
1: 哨兵選舉的票數. 通常數量> 哨兵 1/2
5)修改宕機的超時時間
6)啓動哨兵 redis-sentinel sentinel.conf
注意:配置哨兵前必須配置主從結構
Spring整合哨兵
1.編輯properties文件
#redis哨兵配置
redis.sentinels=192.168.175.129:26379
2.編輯配置類
@Configuration //標識配置類
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig { @Value("${redis.sentinels}") private String sentinels; /*實現哨兵的配置*/ @Bean //定義哨兵池對象 public JedisSentinelPool pool() { Set<String> set = new HashSet<>(); set.add(sentinels); return new JedisSentinelPool("mymaster",set); } //規則:能夠爲bean的方法自動的注入參數對象 //方法2:指定ID進行注入 //@Qualifier("jedisSentinelPool")JedisSentinelPool pool @Bean @Scope("prototype") public Jedis jedis(JedisSentinelPool pool) { return pool.getResource(); } }
3.編輯切面
@Component //將類交給容器管理
@Aspect //標識切面
public class CacheAspect {
@Autowired
private Jedis jedis; //private SharedJedis jedis; //若是是環繞通知,則參數必須寫ProceedingJoinPoint,必須位於第一位 @Around("@annotation(cacheFind)") ............