日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis基础

發(fā)布時間:2023/11/30 数据库 36 coder
生活随笔 收集整理的這篇文章主要介紹了 Redis基础 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Nosql

NoSQL:即Not-OnlySQL(泛指非關(guān)系型的數(shù)據(jù)庫),作為關(guān)系型數(shù)據(jù)庫的補充。
作用:應(yīng)對基于海量用戶和海量數(shù)據(jù)前提下的數(shù)據(jù)處理問題。

Redis介紹

概念

Redis(REmote DlctionaryServer)是用C語言開發(fā)的一個開源的高性能鍵值對(key-value)數(shù)據(jù)庫

特征

1.數(shù)據(jù)間沒有必然的關(guān)聯(lián)關(guān)系

2.內(nèi)部采用單線程機制進(jìn)行工作

3.高性能

4.支持多種數(shù)據(jù)類型

5.支持持久化,可以存硬盤。

應(yīng)用

熱點信息,時效性信息,分布式數(shù)據(jù)共享,消息隊列,即使信息查詢。

在虛擬機上啟動redis服務(wù)

通過指定的配置文件啟動redis服務(wù),

  1. 查看進(jìn)程:ps -ef | grep redis
  2. 進(jìn)入配置文件的目錄cd /usr/local/redis/bin/
  3. 輸入 ./redis-server redis.conf
  4. 輸入 ./redis-cli
  5. 關(guān)閉服務(wù)并退出:shutdown 然后:exit

鍵值對

設(shè)置鍵值對

? 語法:set key value

獲取鍵值對

? 語法:get key

判斷鍵是否存在:exist key

設(shè)置過期時間: expire key 時間

查看過期時間: ttl key

查看當(dāng)前key的數(shù)據(jù)類型:> type key

刪除key:del key

redis共有16個庫

選擇數(shù)據(jù)庫

語法:select 數(shù)字

查看

查看大小:dbsize

查看數(shù)據(jù)庫所有的鍵:keys *

清空

清空當(dāng)前數(shù)據(jù)庫:flushdb

清空所有:flushall

基本數(shù)據(jù)類型

String

追加字符串,不存在則新建:append key1 "hello"

獲取字符串長度:strlen key1

初始瀏覽量為0 :set views 0

設(shè)置自增1:incr views

設(shè)置自減1:decr views

可以設(shè)置步長。每次的增長值 : INCRBY views 10 #

獲取指定范圍的值: GETRANGE key 起始點 結(jié)束點

獲取所有長度的值: GETRANGE key 0 -1

設(shè)置多個值:

mset key value key value ……

mget key key key

msetnx 原子性操作設(shè)置多個值

設(shè)置過期時間和值:

設(shè)置key3 的值為 he11o,30秒后過期: setex key3 30 "he1lo"

先get然后在set: getset

List

LPuSH key value

LPUSH list one #將一個值或者多個值,插入到列表頭部(左)

RPUSH key value

Rpush list righr #將一個值或者多個值,插入到列表位部(右)

lrange key start end

LRANGE list 0 1 #通過區(qū)間獲取具體的值!

LROR key #移出并獲取列表的第一個元素

lindex list 1 #通過下標(biāo)獲得list 中的某一個值!

Llen list # 返回列表的長度

lrem key count value

lrem list 1 one # 移除list集合中指定個數(shù)的value,精確匹配

ltrim list 1 2 #截取指定的長度!

lset 將列表中指定下標(biāo)的值替換為另外一個值,更新操作

lset list 0 item #如果存在,更新當(dāng)前下標(biāo)的值

在指定元素前后插入指定的值

LINSERT mylist after world new

set

set集合中添加

sadd key value

sadd myset "hello"

查看指定set的所有值

smembers key

SMEMBERS myset

判斷某一個值是不是在set集合中!

sismember key value

SISMEMBER myset hello

查看個數(shù)

scard key

scard myset

移除set集合中的指定元素

srem key value

srem myset hello

獲取隨機

SRANDMEMBER myset

SRANDMEMBER myset 2

smove myset myset2 "kuangshen"# 將一個指定的值,移動到另外一個set集合!

SDIFF key1 key2 差集

SINTER key1 key2 交集

SUNION key1 key2 并集

hash

hset 集合名 key value

hset myhash field1 hello

# set一個具體key-vlaue

獲取一個字段值

hget 集合名 key鍵

hget myhash field1

添加多個 key-vlaue

hmset 集合 key鍵1 key鍵2

hmset myhash field1 hello field2 world

獲取多個字段值

hmget 集合名 key1 key2

hmget myhash field1 field2

獲取全部的數(shù)據(jù)

hget 集合名

hgetall myhash

刪除hash指定key字段!對應(yīng)的value值也就消失了!

hdel 集合名 key

hdel myhash field1

判斷hash中指定字段是否存在!

HEXISTS myhash field1

只獲得所有field

hkeys 集合名

hkeys myhash

只獲得所有value

hvals 集合名

hvals myhash

設(shè)置自動增長

HINCRBY myhash field3 1

HINCRBY myhash field3 -1

如果不存在則可以設(shè)置

hsetnx myhash field4 hello

如果存在則不能設(shè)置

hsetnx myhash field4 world

zset

zset在set的基礎(chǔ)上增加了一個值,set k1 v1 zset k1 score1 v1

添加一個值

zadd key score value

zadd myset 1 one

添加多個值

zadd myset 2 two 3 three

獲取范圍值

zrange key start end

zrange myset 0 -1

顯示全部內(nèi)容從小到大

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

移除元素

zrem key value


特殊數(shù)據(jù)類型

地理位置geostital

創(chuàng)建一個元素

geoadd key 緯度 經(jīng)度 成員

geoadd city 116.40 39.90 beijing

獲取坐標(biāo)

geopos city beijing

獲取兩者之間的距離

geodist key value1 value2 單位

geodist city beijing shanghai km

相關(guān)范圍內(nèi)的城市

georadius key 緯度 經(jīng)度 距離 單位 withdist

找出指定位置內(nèi)的其他元素

georadiusbymember key value 距離 單位

bitmaps

位存儲

統(tǒng)計用戶信息,活躍,不活躍!登錄、未登錄!打卡,365打卡!兩個狀態(tài)的,都可以使用Bitmaps!

Bitmaps位圖,數(shù)據(jù)結(jié)構(gòu)!都是操作二進(jìn)制位來進(jìn)行記錄,就只有0和1兩個狀態(tài)!

365天=365 bit 1字節(jié)=8bit46個字節(jié)左右!

設(shè)置一個元素

setbit key offset value

查看

getbit sign offset


事務(wù)

Redis 事務(wù)本質(zhì):一組命令的集合!一個事務(wù)中的所有命令都會被序列化,在事務(wù)執(zhí)行過程的中,會按照順序執(zhí)行! 一次性、順序性、排他性!執(zhí)行一系列的命令!

Redis命令保證原子性,但是事務(wù)不保證原子性!

redis事務(wù):

1 開啟事務(wù):開啟一個事務(wù)

multi

2 命令入隊:將命令放入事務(wù)

set key value

3 執(zhí)行事務(wù):執(zhí)行事務(wù)中的命令

exec

4 取消事務(wù):事務(wù)中的命令都不會被執(zhí)行

discard

eg:

# 正常執(zhí)行
127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK

#取消事務(wù)
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> DISCARD
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> DISCARD
OK
127.0.0.1:6379> get k3
(nil)

如果在入隊的命令中有錯誤的命令,

如果是編譯時異常,那么所有命令都不會被執(zhí)行。

如果是運行時異常,那么其他命令正常執(zhí)行,僅有錯誤的命令拋出錯誤信息。


悲觀鎖

很悲觀,什么時候都要加鎖。

樂觀鎖

很樂觀,認(rèn)為什么時候都不會出問題,所以不會上鎖!更新數(shù)據(jù)的時候去判斷一下,在此期間是否有人修改過這個數(shù)據(jù),
獲取version
更新的時候比較version

使用watch命令當(dāng)作redis的樂觀鎖操作

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> INCRBY money 10
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 20
127.0.0.1:6379> 

unwatch

如果發(fā)現(xiàn)事務(wù)執(zhí)行失敗,就先解鎖


jedis

Jedis是redis的java版本的客戶端實現(xiàn),使用Jedis提供的Java API對Redis進(jìn)行操作,是Redis官方推崇的方式;并且,使用Jedis提供的對Redis的支持也最為靈活、全面;不足之處,就是編碼復(fù)雜度較高。

導(dǎo)入依賴

簡單語法:

Jedis jedis = new Jedis( host: "127.0.0.1", port: 6379);
System.out.println("清空數(shù)據(jù):"+jedis.flushDB());
System.out.println("判斷某個鍵是否存在:"+jedis.exists( key: "username"));
System.out.println("新增<'username','haha'>的鍵值對:"+jedis.set("username","haha");
System.out.println("新增<'password','mima'>的鍵值對:"+jedis.set("password","mima");
System.out.print("系統(tǒng)中所有的鍵如下:");
Set<String> keys = jedis.keys( pattern:"*");
System.out.println(keys);
System.out.println("刪除鍵password:"+jedis.del( key:"password"));
System.out.println("判斷鍵password是否存在:"+jedis.exists( key: "password"));
System.out.println("查看鍵username所存儲的值的類型:"+jedis.type( key: "username"));
System.out.println("隨機返回key空間的一個:"+jedis.randomKey());
System.out.println("重命名key:"+jedis.rename( oldkey: "username", newkey: "name"));
System.out.println("取出改后的name: "+jedis.get("name"));
System.out.println("按索引查詢:"+jedis.select( index: 0));
System.out.println("刪除當(dāng)前選擇數(shù)據(jù)庫中的所有key:"+jedis.flushDB());
System.out.println("返回當(dāng)前數(shù)據(jù)庫中key的數(shù)目:"+jedis.dbSize());
System.out.println("刪除所有數(shù)據(jù)庫中的所有key:"+jedis.flushAll());                                   
                   
                      
System.out.println(jedis.set("key1","value1"));
System.out.println(jedis.set("key2","value2"));
System.out.println(jedis.set("key3","value3"));
System.out.println("刪除鍵key2:"+jedis.del( key: "key2"));
System.out.println("獲取鍵key2:"+jedis.get("key2"));
System.out.println("修改key1:"+jedis.set("key1","value1Changed"));
System.out.println("獲取key1的值:"+jedis.get("key1"));
System.out.println("在key3后面加入值:"+jedis.append("key3", "End"));
System.out.println("key3的值:"+jedis.get("key3"));
system.out.println("增加多個鍵值對:"+jedis.mset( "key01","value01","key02","va2");//(keys,values)
system.out.println("獲取多個鍵值對:"+jedis .mget( "key01","key02","key03"));//(...keys: )
                   
                   
jedis.flushDB(); //清空數(shù)據(jù)庫
System.out.println("===========新增鍵值對防止覆蓋原先值============="):
System.out.println(jedis.setnk("key1","value1"));
System.out.println(jedis.setnx("key2","value2"));
System.out.println(jedis.setnx("key2","value2-new"));
System.out.println(jedis.get("key1"));
System.out.println(jedis.get("key2"));
                   
System.out.println("===========新增鍵值對并設(shè)置有效時間=============");
System.out.print1n(jedis.setex("key3", 2,"value3")); //(key,seconds,val)
System.out.print1n(jedis.get("key3"));
                   
//清空數(shù)據(jù)庫,setnx(key,value) 
jedis.flushDB();
System.out.print1n("===========新增鍵值對防止覆蓋原先值=========");
System.out.println(jedis.setnx("key1","value1"));
System.out.println(jedis.setnx("key2","value2"));
System.out.println(jedis.setnx("key2","value2-new"));
System.out.println(jedis.get("key1"));
System.out.print1n(jedis.get("key2"));
                   
System.out.println("===========新增鍵值對并設(shè)置有效時間:=========");
System.out.println(jedis.setex((key:"key3",seconds:2,Ivalue: "value3"));
System.out.println(jedis.get("key3"));
try {
TimeUnit.SECONDS.sleep(timeout: 3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(jedis.get("key3"));



//List集合
jedis.flushDB();//清空數(shù)據(jù)庫
System.out.print1n("===========添加一個1ist===========");
jedis.lpush(key:"collections",...strings:"ArrayList","Vector","Stack","HashMap","WeakHashMap","List");
jedis.lpush( key: "collections",...strings:"Hashset");
jedis.lpush( key: "collections",...strings: "TreeSet");
jedis.1push( key: "collections",...strings: "TreeMap");
System.out.println("collections的內(nèi)容:"+jedis.lrange( key: "collections",start: 0,stop:-1));//0,-1代表所有
System.out.println("collections區(qū)間0-3的元素:"+jedis.1range( key: "collections", start:0,stop:3));
System.out.println("刪除指定元素個數(shù):"+jedis.1rem( key: "collections", count: 2, value: "HashMap"));
System.out.print1n("collections的內(nèi)容:"+jedis.lrange( key: "collections",start: 0, stop: -1));
System.out.println("刪除下表0-3區(qū)間之外的元素:"+jedis.ltrim( key: "collections", start: 0, stop:3));
System.out.print1n("collections的內(nèi)容:"+jedis.lrange( key: "collections", start: 0, stop:-1));
system.out.println("collections列表出棧(左端):"+jedis.lpop( key:"collections"));
System.out.println("collections的內(nèi)容:"+jedis.lrange( key:"collections", start: 0, stop:-1));
System.out.println("collections添加元素,從列表右端,與lpush相對應(yīng):"+jedis.rpush( key: "collections", value:"list1");
System.out.println("collections的內(nèi)容:“+jedis.1range( key: "collections",start: 0, stop:-1));
System.out.print1n("collections列表出棧(右端):"+jedis.rpop( key: "collections"));
System.out.println("collections的內(nèi)容:"+jedis.lrange( key: "collections",start: 0, stop:-1));
System.out.println("修改collections指定下標(biāo)1的內(nèi)容:"+jedis.lset( key: "collections", index: 1, value:"list");
System.out.print1n("collections的內(nèi)容:"+jedis.lrange( key: "collections", start: e, stop:-1));
System.out.print1n("===================");
System.out.println("collections的長度:"+jedis.llen( key: "collections"));
System.out.print1n("獲取collections下標(biāo)為2的元素:"+jedis.lindex( key: "collections", index: 2));
System.out.println("===================");
jedis.lpush( key: "sortedList", ...strings: "3","6","2","0","7","4");
System.out.println("sortedList排序前:"+jedis.lrange( key: "sortedList", start: 0, stop:-1));
System.out.println(jedis.sort( key: "sortedList"));
                   

//set集合
jedis.flushDB();//清空數(shù)據(jù)庫
System.out.println("============向集合中添加元素(不重復(fù))============");
System.out.println(jedis.sadd( key: "eleSet", ...members: "e1" ,"e2" ,"e4","e3","e0","e8","e7","e5"));
System.out.print1n(jedis.sadd( key: "eleSet", ...members: "e6"));
System.out.println(jedis.sadd( key: "eleset", ...members: "e6"));
System.out.println("eleSet的所有元素為:"+jedis.smembers( key: "eleSet"));
System.out.println("刪除一個元素e0:"+jedis.srem(key: "eleSet", ...members: "e0"));
System.out.println("eleSet的所有元素為:"+jedis.smembers( key: "eleSet"));
System.out.println("刪除兩個元素e7和e6:"+jedis.srem( key: "eleset", ...members: "e7","e6"));
System.out.println("eleSet的所有元素為:"+jedis.smembers( key: "eleSet"));
System.out.println("隨機的移除集合中的一個元素:"+jedis.spop( key: "eleSet"));
System.out.println("隨機的移除集合中的一個元素:"+jedis.spop( key: "eleset"));
System.out.println("eleSet的所有元素為:"+jedis.smembers( key: "eleSet"));
System.out.println("eleSet中包含元素的個數(shù):"+jedis.scard( key: "eleset"));
System.out.println("e3是否在eleset中:"+jedis.sismember( key: "eleset", member: "e3"));
System.out.println("e1是否在eleSet中:"+jedis.sismember( key: "eleSet", member: "e1"));
System.out.println("e1是否在eleSet中:"+jedis.sismember( key: "eleset", member: "e5"));             
System.out.println(jedis.sadd(key:"eleSet1",...members:"e1","e2","e4","e3","e0","e8","e7","e5"));
System.out.println(jedis.sadd( key: "eleSet2",...members: "e1","e2","e4","e3","e0","e8"));
System.out.println("將eleSet1中刪除e1并存入eleSet3中:"+jedis.smove( srckey: "eleSet1", dstkey: "eleSet3",dstvalue:"");
System.out.println("將eleSet1中刪除e2并存入eleSet3中:"+jedis.smove( srckey: "eleSet1", dstkey: "eleSet3",dstvalue:"val");
System.out.println("eleSet1中的元素:"+jedis.smembers( key: "eleSet1"));
System.out.println("eleSet3中的元素:"+jedis. smembers ( key:"eleSet3"));
System.out.print1n("============集合運算=================");
System.out.println("eleSet1中的元素:"+jedis.smembers ( key: "eleSet1"));
System.out.println("eleSet2中的元素:"+jedis.smembers( key:"eleSet2"));

                   
                   
//hashMap
jedis.flushDB();
Map<String,String> map = new HashMap<>();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
map.put("key4","value4");
//添加名稱為hash (key)的hash元素
jedis.hmset( key: "hash",map);
//向名稱為hash的hash中添加key為key5,value為value5元素
jedis.hset( key: "hash", field: "key5", value: "value5");
System.out.println("散列hash的所有鍵值對為:"+jedis.hgetA1l( key: "hash"));
System.out.println("散列hash的所有鍵為:"+jedis.hkeys("hash"));
System.out.println("散列hash的所有值為:"+jedis.hvals( key: "hash"));
System.out.println("將key6保存的值加上一個整數(shù),如果key6不存在則添加key6:"+jedis.r
System.out.println("散列hash的所有鍵值對為:"+jedis.hgetAl1( key: "hash"));
System.out.println("將key6保存的值加上一個整數(shù),如果key6不存在則添加key6:“+jedis.r
system.out.println("散列hash的所有鍵值對為:"+jedis.hgetAl1(key: "hash"));
System.out.println("刪除一個或者多個鍵值對:"+jedis.hdel( key: "hash", ...fields: "key2");
System.out.println("散列hash的所有鍵值對為:"+jedis.hgetA11( key: "hash"));
System.out.println("散列hash中鍵值對的個數(shù):"+jedis.hlen( key:"hash"));
System.out.println("判斷hash中是否存在key2:"+jedis.hexists(key: "hash",field: "key2");
System.out.println("判斷hash中是否存在key3:"+jedis.hexists(key: "hash", field: "key3");
System.out.println("獲取hash中的值:"+jedis.hmget( key: "hash",...fields: "key3"));
System.out.println("獲取hash中的值:"+jedis.hmget( key: "hash", ...fields: "key3","key4");

                                            
                                            
//事務(wù)
jedis.flushDB();|
JSONObject json0bject = new JSONObject();
json0bject.put("hello","world");
json0bject.put("name","kuangshen");
// 開啟事務(wù)
Transaction multi = jedis.multi();
String result= json0bject.toJSONString();
try{
multi.set("user1",result);
multi.set("user2",result);
int i = 1/0://代碼拋出異常事務(wù),執(zhí)行失敗!
}catch(Exception e){
    e.printStackTrace();
}
                   

SpringBoot整合

修改配置文件:

#redis的配置信息
spring.data.redis.host=192.168.80.128
spring.data.redis.port=6379
#最多獲取數(shù)
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=-1ms
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=0

測試:

redisTemplate 操作不同的數(shù)據(jù)類型,api和我們的指令是一樣的
opsForValue 操作字符串 類似String
opsForList 操作List 類似List
opsForSet
opsForHash
opsForzset
opsForGeo
opsForHyperLogLog

除了基本的操作,我們常用的方法都可以直接通過redisTemplate操作,比如事務(wù),和基本的CRUD

獲取redis的連接對象

@Autowired
private RedisTemplateredisTemplate;

public void redis(){
    RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
	connection.fLushDb();
	connection.flushAll();
    redisTemplate.opsForValue().set("mykey","redis111");
	System.out.println(redisTemplate.opsForValue().get("mykey"));
}

配置自己的序列化方式

@Configuration
public class RedisConfig {

// 自己定義了一個RedisTemplate
@Bean
@SuppressWarnings("al1")
public RedisTemplate<String, object> redisTemplate(RedisConnectionFactory factory){
// 我們?yōu)榱俗约洪_發(fā)方便,一般直接使用<String,Object>
RedisTemplate<String,Object> template = new RedisTemplate<String,0bject>();
template.setConnectionFactory(factory);
// Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(0bject.cl
ObjectMapper om = new 0bjectMapper();
om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(0bjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.set0bjectMapper(om);
// String 的序列化 
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用string的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用string的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
 }
 } 


Redis配置文件

redis里的單位配置,忽略大小寫。

導(dǎo)入其他配置文件:

include /path/to/local.conf

include /path/to/other.conf

網(wǎng)絡(luò)

bind 127.0.0.1 #綁定的ip

protected-mode yes #保護(hù)模式
port 6379 #端口設(shè)置

通用 general

daemonize yes #以守護(hù)進(jìn)程的方式運行,默認(rèn)是no,我們需要自己開啟為yes!

pidfile /var/run/redis_6379.pid #如果以后臺的方式運行,我們就需要指定一個pid 文件!

#日志

#specify the server verbosity level.

#This can be one of:

#debug (a lot of information, useful for development/testing)

#verbose (many rarely useful info, but not a mess like the debug level)

#notice (moderately verbose, what you want in production probably) #生產(chǎn)環(huán)境

#warning (only very important / critical messages are 1ogged)

loglevel notice

logfile,"" #日志的文件位置名

databases 16 #數(shù)據(jù)庫的數(shù)量,默認(rèn)是16個數(shù)據(jù)庫

always-show-logo yes #是否總是顯示LOGO

持久化

持久化,在規(guī)定的時間內(nèi),執(zhí)行了多少次操作,則會持久化到文件.rdb.aof
redis是內(nèi)存數(shù)據(jù)庫,如果沒有持久化,那么數(shù)據(jù)斷電及失!

RDB配置:


#如果900s內(nèi),如果至少有一個1key進(jìn)行了修改,我們及進(jìn)行持久化操作

save 900 1

#如果300s內(nèi),如果至少10key進(jìn)行了修改,我們及進(jìn)行持久化操作

save 300 10

#如果60s內(nèi),如果至少10000 key進(jìn)行了修改,我們及進(jìn)行持久化操作

save 60 10000

#我們之后學(xué)習(xí)持久化,會自己定義這個測試!

stop-writes-on-bgsave-error yes

#持久化如果出錯,是否還需要繼續(xù)工作!

rdbcompression yes  #是否壓縮rdb 文件,需要消耗一些cpu資源!

rdbchecksum yes  #保存rdb文件的時候,進(jìn)行錯誤的檢查校驗!

dir ./   #rdb 文件保存的目錄!

設(shè)置密碼

獲取當(dāng)前的密碼:config get requirepass

設(shè)置redis的密碼:config set requirepass "123456"

使用密碼進(jìn)行登錄: auth 123456

客戶端

設(shè)置能連接上redis的最大客戶端的數(shù)量 : maxclients 10000

redis 配置最大的內(nèi)存容量: maxmemory <bytes>

maxmemory-policy noeviction #內(nèi)存到達(dá)上限之后的處理策略

1、volatile-lru:只對設(shè)置了過期時間的key進(jìn)行LRU(默認(rèn)值)
2、al1keys-lru:刪除1ru算法的key
3、volatile-random:隨機刪除即將過期key
4、a11keys-random:隨機刪除
5、volatile-ttl:刪除即將過期的
6、noeviction :永不過期,返回錯誤

觸發(fā)機制

1、save的規(guī)則滿足的情況下,會自動觸發(fā)rdb規(guī)則
2、執(zhí)行 flushall命令,也會觸發(fā)我們的rdb規(guī)則!
3、退出redis,也會產(chǎn)生rdb文件!
備份就自動生成一個dump

如何恢復(fù)rdb文件

1、只需要將rdb文件放在我們redis啟動目錄就可以,redis啟動的時候會自動檢查dump.rdb恢復(fù)其中的內(nèi)容
2、查看需要存在的位置

config get dir

1)"dir"
2)"/usr/local/bin" # 如果在這個目錄下存在dump.rdb 文件,啟動就會自動恢復(fù)其中的數(shù)據(jù)

優(yōu)點:
1、適合大規(guī)模的數(shù)據(jù)恢復(fù)!
2、對數(shù)據(jù)的完整性要不高!
缺點:
1、需要一定的時間間隔進(jìn)程操作!如果redis意外宕機了,這個最后一次修改數(shù)據(jù)就沒有的了
2、fork進(jìn)程的時候,會占用一定的內(nèi)容空間!!

AOF配置

appendonly no #默認(rèn)是不開啟aof模式的,默認(rèn)是使用rdb方式持久化的,在大部分所有的情況下,rdb完全夠用!

appendfilename "appendonly.aof" #持久化的文件的名字

appendfsync always #每次修改都會 sync。消耗性能
appendfsync everysec #每秒執(zhí)行一次sync,可能會丟失這1s的數(shù)據(jù)!

appendfsync no #不執(zhí)行 sync,這個時候操作系統(tǒng)自己同步數(shù)據(jù),速度最快!

搜索配置文件內(nèi)容:

vim 文件

:/搜索內(nèi)容 n下一個

如果這個 aof 文件有錯誤,這時候redis 是啟動不起來的嗎,我們需要修復(fù)這個aof文件redis 給我們提供了一個工具 redis-check-aof --fix

消息訂閱

關(guān)注消息后,消息發(fā)出者可以發(fā)出訂閱者都收到的消息。

發(fā)送端:

127.0.0.1:6379> PUBLISH hello nihao
(integer) 1
127.0.0.1:6379> PUBLISH hello haha
(integer) 1
127.0.0.1:6379> 

接收端

127.0.0.1:6379> SUBSCRIBE hello
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "hello"
3) (integer) 1
1) "message"
2) "hello"
3) "nihao"
1) "message"
2) "hello"
3) "haha"

redis主從復(fù)制

主從復(fù)制,讀寫分離!80%的情況下都是在進(jìn)行讀操作!減緩服務(wù)器的壓力!架構(gòu)中經(jīng)常使用!一主二從!

主從復(fù)制,是指將一臺Redis服務(wù)器的數(shù)據(jù),復(fù)制到其他的Redis服務(wù)器。前者稱為主節(jié)點(master/leader),后者稱為從節(jié)點(slave/follower);數(shù)據(jù)的復(fù)制是單向的,只能由主節(jié)點到從節(jié)點。Master以寫為主,Slave以讀為主。

注意:只配從庫不配主庫

查看當(dāng)前庫的信息: info replication

127.0.0.1:6379> info replication
# Replication
role:master #角色
connected_slaves:0  #從機數(shù)量
master_failover_state:no-failover
master_replid:91336488202d1d08d9ddc463852f4c40d2950b7c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

可以測試:

復(fù)制3個配置文件,然后修改對應(yīng)的信息
1、端口
2、pid 名字
3、log文件名字
4、dump.rdb 名字

默認(rèn)情況下,每臺Redis服務(wù)器都是主節(jié)點

配置從節(jié)點,認(rèn)老大:

Slaveof host port

真實的從主配置應(yīng)該在配置文件中配置,這樣的話是永久的,我們這里使用的是命令,暫時的!

主機負(fù)責(zé)寫,從機負(fù)責(zé)讀

Slave 啟動成功連接到master后會發(fā)送一個sync同步命令

Master 接到命令,啟動后臺的存盤進(jìn)程,同時收集所有接收到的用于修改數(shù)據(jù)集命令,在后臺進(jìn)程執(zhí)行完畢之后,master將傳送

整個數(shù)據(jù)文件到slave,并完成一次完全同步。

全量復(fù)制:而slave服務(wù)在接收到數(shù)據(jù)庫文件數(shù)據(jù)后,將其存盤并加載到內(nèi)存中。

增量復(fù)制:Master繼續(xù)將新的所有收集到的修改命令依次傳給slave,完成同步

但是只要是重新連接master,一次完全同步(全量復(fù)制)將被自動執(zhí)行

總結(jié)

以上是生活随笔為你收集整理的Redis基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。