最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis過期Key刪除策略和內(nèi)存淘汰策略的實(shí)現(xiàn)

 更新時(shí)間:2024年02月19日 09:04:19   作者:Surpass余sheng軍  
當(dāng)內(nèi)存使用達(dá)到上限,就無法存儲更多數(shù)據(jù)了,為了解決這個(gè)問題,Redis內(nèi)部會有兩套內(nèi)存回收的策略,過期Key刪除策略和內(nèi)存淘汰策略,本文就來詳細(xì)的介紹一下這兩種方法,感興趣的可以了解一下

Redis之所以性能強(qiáng),最主要的原因就是基于內(nèi)存存儲,然而單節(jié)點(diǎn)的Redis其內(nèi)存大小不宜過大,否則會影響持久化或主從同步的性能。

Redis內(nèi)存滿了,會發(fā)生什么?

  • 在Redis的運(yùn)行內(nèi)存達(dá)到了某個(gè)閾值,就會觸發(fā)內(nèi)存淘汰機(jī)制  =>  防止把內(nèi)存撐爆,這個(gè)閾值就是我們設(shè)置的最大運(yùn)行內(nèi)存。 

我們可以通過修改redis.conf配置文件來設(shè)置Redis的最大內(nèi)存,配置項(xiàng)為maxmemory:

  • Redis默認(rèn)情況下是沒有對最大內(nèi)存大小做限制的,默認(rèn)情況下Redis就是根據(jù)你當(dāng)前的服務(wù)器里面,當(dāng)前最多可以申請到的內(nèi)存大小來去做限制! 
# 格式:
# maxmemory <bytes>
# 例如:
maxmemory 1gb

當(dāng)內(nèi)存使用達(dá)到上限,就無法存儲更多數(shù)據(jù)了,因此,為了解決這個(gè)問題,Redis內(nèi)部會有兩套內(nèi)存回收的策略:

  • 內(nèi)存過期策略
  • 內(nèi)存淘汰策略

內(nèi)存過期策略 - 過期key處理 - 過期刪除策略

如何設(shè)置過期時(shí)間?

  • expire key n秒     
  • pexpire key  n毫秒     
  • set   key  value  ex  n秒   
  • set  key  value nx  n毫秒

查看某個(gè)key剩余的存活時(shí)間:TTL  key 

  • 我們可以通過expire / EX命令給Redis的key設(shè)置TTL(過期時(shí)間 / 存活時(shí)間),單位:秒,當(dāng)key的TTL到期以后,即當(dāng)過期時(shí)間到了以后,再次訪問該key時(shí)返回的是nil,說明這個(gè)Key已經(jīng)不存在了,對應(yīng)的內(nèi)存也得到釋放,從而起到內(nèi)存回收的目的。
# 寫入一條數(shù)據(jù)
set num 123
# 設(shè)置20秒過期時(shí)間
expire num 20
# 寫入一條數(shù)據(jù)并設(shè)置20s過期時(shí)間
set num EX 20

Redis是如何知道一個(gè)key是否過期呢?

  • Redis本身是一個(gè)典型的key-value的鍵值型內(nèi)存存儲數(shù)據(jù)庫,因此所有的key-value都保存在Dict結(jié)構(gòu)中,在其redisDb結(jié)構(gòu)體中,有兩個(gè)Dict,也就是哈希表:一個(gè)用來記錄KEY-VALUE鍵值對(當(dāng)然存的不是真正的Key-Value,存儲的其實(shí)是RedisObject對應(yīng)的內(nèi)存地址的指針),另一個(gè)用來記錄key的TTL。

過期字典存儲在 redisDb 結(jié)構(gòu)中,如下: 

來看下redisDb的底層源碼:

typedef struct redisDb {
    dict dict;                 / The keyspace for this DB , 也就是存放KEY和VALUE的哈希表*/
    dict *expires;              /* 同樣是哈希表,但保存的是設(shè)置了TTL的KEY,及其到期時(shí)間*/
    dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP)*/
    dict *ready_keys;           /* Blocked keys that received a PUSH */
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS /
    int id;                     / Database ID, 0 ~ 15 /
    long long avg_ttl;          / Average TTL, just for stats /
    unsigned long expires_cursor; / Cursor of the active expire cycle. */
    list *defrag_later;         /* List of key names to attempt to defrag one by one, gradually. */
} redisDb;

每當(dāng)我們對一個(gè)key設(shè)置了過期時(shí)間后,Redis會把該key帶上過期時(shí)間存儲到一個(gè)過期字典(expires dict)中,也就是說「過期字典」保存了數(shù)據(jù)庫中所有 key 的過期時(shí)間。 

當(dāng)我們查詢一個(gè) key 時(shí),Redis 首先檢查該 key 是否存在于過期字典中:

  • 如果不在,則正常讀取鍵值;
  • 如果存在,則會獲取該 key 的過期時(shí)間,然后與當(dāng)前系統(tǒng)時(shí)間進(jìn)行比對,如果比系統(tǒng)時(shí)間大,那就沒有過期,否則判定該 key 已過期    =>   查詢到對應(yīng)的TTL,加以判斷即可。

是不是TTL到期就立即刪除了呢? 

TTL(Time To Live)的含義是存活時(shí)間。 

  • Redis并不會在Key過期時(shí)立刻刪除KEY,因?yàn)橐獙?shí)現(xiàn)這樣的效果就必須給每一個(gè)過期Key設(shè)置一個(gè)定時(shí)器,并監(jiān)控這些Key的過期狀態(tài),然后去做判斷,在key過期的那一刻給它立刻刪掉   =>  定時(shí)刪除,它的優(yōu)點(diǎn)就是保證過期key會被盡快刪除,也就是內(nèi)存可以盡快得到釋放,因此,定時(shí)刪除對內(nèi)存是最友好的;
  • 如果說我們的key比較少那還好,但是如果我們的key非常的多,達(dá)到數(shù)十萬甚至數(shù)百萬,那么這些key如果我們都給它設(shè)置這樣一個(gè)定時(shí)器,無論是對CPU還是對內(nèi)存都會帶來極大的負(fù)擔(dān),這樣一來,就會嚴(yán)重影響到Redis服務(wù)本身的一個(gè)性能,所以說這個(gè)是沒有辦法接受的,因此,我們在實(shí)際應(yīng)用當(dāng)中,Redis采用的并不是立即刪除,而是惰性刪除  + 周期刪除  =>   Redis 使用的過期刪除策略是「惰性刪除+定期刪除」這兩種策略配和使用,刪除的對象是已過期的 key。

Redis的過期KEY刪除策略有兩種:

  • 惰性刪除

  • 周期刪除或定期刪除

惰性刪除

  • 顧名思義就是TTL過期后不會立刻刪除,惰性刪除策略的做法是,不主動刪除過期鍵,而是在訪問使用一個(gè)key的時(shí)候,判斷當(dāng)前key有沒有設(shè)置TTL過期時(shí)間,如果有,則檢查該key的存活時(shí)間,如果發(fā)現(xiàn)key已經(jīng)過期才執(zhí)行刪除操作,如果沒有過期,不做任何處理,然后返回正常的鍵值對給客戶端。 

惰性刪除策略的優(yōu)缺點(diǎn):

優(yōu)點(diǎn):

  • 因?yàn)槊看卧L問時(shí),才會檢查該key是否過期,因此惰性刪除策略可以節(jié)省CPU資源,對CPU時(shí)間最友好。

缺點(diǎn):

  • 如果一個(gè)key已經(jīng)過期,而這個(gè)key又仍然保留在數(shù)據(jù)庫中,那么只要這個(gè)過期key一致沒有被訪問,它所占用的內(nèi)存就不會釋放,會造成一定的內(nèi)存空間浪費(fèi),所以惰性刪除策略對內(nèi)存不友好   =>   這不就是會導(dǎo)致內(nèi)存泄漏嗎???

周期刪除 / 定期刪除策略

  • 顧名思義就是通過一個(gè)定時(shí)任務(wù),每隔一段時(shí)間周期性的從數(shù)據(jù)庫中抽取一定數(shù)量的key進(jìn)行檢查,并刪除其中的過期key。

Redis默認(rèn)會每秒進(jìn)行10次過期檢查(此配置可以通過Redis的配置文件redis.conf進(jìn)行配置,配置鍵為hz,它的默認(rèn)值是hz 10),每次檢查數(shù)據(jù)庫并不是遍歷過期字典中的所有key,而是從數(shù)據(jù)庫中隨機(jī)抽取一定數(shù)量的key進(jìn)行過期檢查:

  • 從過期字典中隨機(jī)抽取20個(gè)key;
  • 檢查這20個(gè)key是否過期,并刪除已過期的key;
  • 如果本輪檢查的已過期key的數(shù)量,超過5個(gè)(5 / 20 = 1 / 4 = 25%),也就是「已過期 key 的數(shù)量」占比「隨機(jī)抽取 key 的數(shù)量」大于 25%,則繼續(xù)隨機(jī)抽查,重復(fù)步驟1;如果已過期的key的比例小于25%,則停止繼續(xù)刪除過期key,退出本輪檢查,然后等待下一輪再檢查。 

可以看到,定期刪除是一個(gè)循環(huán)的流程。

Redis為了保證定期刪除不會出現(xiàn)循環(huán)過度,導(dǎo)致線程卡死現(xiàn)象,為此增加了定期刪除循環(huán)流程的時(shí)間上限,默認(rèn)不會超過25ms,超出時(shí)間限制則退出。 

定期刪除策略的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 定期刪除是Redis的主動刪除策略,它可以確保過期key能夠及時(shí)被刪除

缺點(diǎn):

  • 會占用CPU資源去掃描key,可能會影響到Redis的性能 

可以看到,惰性刪除策略和定期刪除策略都有各自的優(yōu)缺點(diǎn),所以Redis選擇「惰性刪除+定期刪除」這兩種策略配和使用,以求在合理使用 CPU 時(shí)間和避免內(nèi)存浪費(fèi)之間取得平衡。 

如果過期鍵沒有被訪問,而定期刪除又跟不上新鍵產(chǎn)生的速度,內(nèi)存不就慢慢耗盡了嗎? 

內(nèi)存淘汰策略

內(nèi)存淘汰:

  • 就是當(dāng)Redis的內(nèi)存使用達(dá)到設(shè)置的閾值時(shí),Redis就會主動挑選部分key刪除以釋放更多內(nèi)存的流程,這就叫做內(nèi)存淘汰機(jī)制。
  • 內(nèi)存淘汰策略是解決內(nèi)存過大的問題。

內(nèi)存淘汰時(shí)機(jī)

當(dāng)內(nèi)存達(dá)到閾值時(shí)執(zhí)行內(nèi)存淘汰,但問題是Redis什么時(shí)候會去判斷內(nèi)存是否達(dá)到閾值呢?

  • Redis每次執(zhí)行任何命令時(shí),都會判斷內(nèi)存是否達(dá)到閾值。

當(dāng)Redis內(nèi)存不足時(shí)會怎么做?

  • 這取決于配置的內(nèi)存淘汰策略,Redis支持很多種內(nèi)存淘汰策略,例如LRU、LFU、Random,但默認(rèn)的策略是直接決絕新的寫入請求,而如果設(shè)置了其它策略,則會在每次執(zhí)行命令后判斷內(nèi)存占用是否達(dá)到閾值,如果達(dá)到閾值則會基于配置的內(nèi)存淘汰策略嘗試進(jìn)行內(nèi)存淘汰,直到占用內(nèi)存小于閾值為止。 

Redis 內(nèi)存淘汰策略有哪些? 

Redis支持內(nèi)存淘汰,配置參數(shù)maxmemory-policy決定了內(nèi)存淘汰策略,這個(gè)參數(shù)一共有8個(gè)枚舉值,也就是說Redis內(nèi)存淘汰策略共有8種,這八種策略大體分為「不進(jìn)行數(shù)據(jù)淘汰」和「進(jìn)行數(shù)據(jù)淘汰」兩類策略:

1. 不進(jìn)行數(shù)據(jù)淘汰的策略

  • noevictionRedis3.0之后,默認(rèn)的內(nèi)存淘汰策略) :禁止刪除數(shù)據(jù),它表示當(dāng)Redis的運(yùn)行內(nèi)存超過最大設(shè)置內(nèi)存時(shí),也就是當(dāng)Redis內(nèi)存滿時(shí),不淘汰任何鍵值對數(shù)據(jù),而是不再提供服務(wù),不允許寫入新數(shù)據(jù),Redis的寫命令會直接返回錯(cuò)誤信息(但是讀命令還是可以正常返回)。

2. 進(jìn)行數(shù)據(jù)淘汰的策略

針對「進(jìn)行數(shù)據(jù)淘汰」這一類策略,又可以細(xì)分為「在設(shè)置了過期時(shí)間的數(shù)據(jù)中進(jìn)行淘汰」和「在所有數(shù)據(jù)范圍內(nèi)進(jìn)行淘汰」這兩類策略。 在設(shè)置了過期時(shí)間的數(shù)據(jù)中進(jìn)行淘汰:

  • volatile-random:隨機(jī)淘汰設(shè)置了過期時(shí)間的任意鍵值 - 從已設(shè)置過期時(shí)間的數(shù)據(jù)集中任意選擇數(shù)據(jù)淘汰;
  • volatile-ttl從已設(shè)置過期時(shí)間的數(shù)據(jù)集中挑選將要過期的數(shù)據(jù)淘汰:比較key的剩余TTL值,TTL越小越先被淘汰。
  • volatile-lru(Redis3.0 之前,默認(rèn)的內(nèi)存淘汰策略):LRU(Least Recently Used),最近最久未使用,利用LRU算法淘汰所有設(shè)置了TTL過期時(shí)間的鍵值中,最久未使用的鍵值;
  • volatile-lfu(Redis 4.0 后新增的內(nèi)存淘汰策略):LFU(Least Frequently Used),最少頻率使用,淘汰所有設(shè)置了TTL過期時(shí)間的鍵值中,最少使用的鍵值;

在所有數(shù)據(jù)范圍內(nèi)進(jìn)行淘汰:

  • allkeys-random:對全體key,隨機(jī)進(jìn)行淘汰;
  • allkeys-lruLRU(Least Recently Used),最近最久未使用,淘汰全體鍵值中最久未使用的鍵值;
  • allkeys-lfuRedis 4.0 后新增的內(nèi)存淘汰策略)::LFU(Least Frequently Used),最少頻率使用,淘汰整個(gè)鍵值中最少使用的鍵值,即訪問頻率最低的那個(gè)key-value。

比較容易混淆的有兩個(gè)算法:

  • LRU(Least Recently Used),最近最久未使用(根據(jù)訪問時(shí)間淘汰),會選擇淘汰最近最少使用的數(shù)據(jù),用當(dāng)前時(shí)間減去最后一次訪問時(shí)間,這個(gè)值越大則淘汰優(yōu)先級越高。
  • LFU(Least Frequently Used),最少頻率使用(根據(jù)訪問頻率淘汰),LFU 算法是根據(jù)數(shù)據(jù)訪問次數(shù)來淘汰數(shù)據(jù)的,它的核心思想是“如果數(shù)據(jù)過去被訪問多次,那么將來被訪問的頻率也更高”,所以, LFU 算法會統(tǒng)計(jì)每個(gè)key的訪問頻率,值越小淘汰優(yōu)先級越高。 

Redis 4.0開始支持基于LFU算法的淘汰策略! 

Redis為什么新增了LFU淘汰策略?

為什么Redis 4.0有了LFU?

  • 比如Redis中的一個(gè)鍵,之前一直都沒有被訪問過,最近突然被訪問了一次,如果使用LRU淘汰策略就很難被淘汰,因?yàn)長RU會把它定義為熱鍵;
  • 而使用LFU淘汰策略該key就可能很快被淘汰,因?yàn)長RU優(yōu)先淘汰最近未被使用的,而LFU淘汰的是最近訪問頻率最低的。
  • LFU比LRU淘汰更精確,有助于提升Redis的緩存命中率。 

Redis怎么知道某個(gè)KEY的最后一次訪問時(shí)間或者是訪問頻率呢? 

  • redisObject結(jié)構(gòu)體當(dāng)中的lru就是記錄最近一次訪問時(shí)間和訪問頻率的,以低8位無符號數(shù)字來記錄邏輯訪問次數(shù)。
  • 邏輯訪問次數(shù)又是怎么回事呢?8位無符號數(shù)字最大才255,訪問次數(shù)超過255怎么辦?

邏輯訪問次數(shù)是如何計(jì)算的?

  • 由于記錄訪問次數(shù)的只有8bit,即便是無符號數(shù),最大值只有255,不可能記錄真實(shí)的訪問次數(shù),因此LFU的訪問次數(shù)之所以叫做邏輯訪問次數(shù),是因?yàn)椴⒉皇敲看蝛ey被訪問都計(jì)數(shù),Redis統(tǒng)計(jì)的其實(shí)是邏輯訪問次數(shù),這其中是一個(gè)計(jì)算公式,會根據(jù)當(dāng)前的訪問次數(shù)做計(jì)算,結(jié)果要么是次數(shù) + 1,要么是次數(shù)不變,且最大不超過255,除此以外,邏輯訪問次數(shù)還有一個(gè)衰減周期,訪問次數(shù)會隨時(shí)間衰減,默認(rèn)為1分鐘,即每隔1分鐘邏輯訪問次數(shù)會 -1,這樣邏輯訪問次數(shù)就能基本反映出一個(gè)key的訪問熱度了。

 顯然LFU的基于訪問頻率的統(tǒng)計(jì)更符合我們的淘汰目標(biāo),因此官方推薦使用LFU算法。 

內(nèi)存淘汰用到的是LRU算法嗎?

  • 嗯...Redis使用的是近似LRU算法,傳統(tǒng)LRU算法的實(shí)現(xiàn)需要一個(gè)雙向鏈表來記錄數(shù)據(jù)最近被訪問的順序,最新操作的鍵會被移動到表頭,當(dāng)需要內(nèi)存淘汰時(shí),只需要刪除鏈表尾部的數(shù)據(jù)即可,因?yàn)殒湵砦膊康脑鼐痛碜罹梦幢皇褂玫脑亍?nbsp;
  • 但是Redis中的KEY可能有數(shù)百萬甚至更多,出于節(jié)省內(nèi)存的考慮,Redis的LRU算法并非完整的實(shí)現(xiàn),Redis的算法并不是真正的LRU,而是一種基于抽樣的近似LRU算法!
  • Redis采用的是抽樣法,即每次抽樣一定數(shù)量(maxmemory-samples)的key,然后和目前維持的淘汰候選池綜合比較,然后基于內(nèi)存策略做排序,找出淘汰優(yōu)先級最高的,刪除這個(gè)key,這就使得算法的結(jié)果更接近于真正的LRU算法了,特別是在抽樣值較高的情況下(例如10),可以達(dá)到與真正的LRU接近的結(jié)果。

當(dāng)Redis作為緩存使用的時(shí)候,推薦使用allkeys-lru淘汰策略,該策略會將最近最久未使用的key淘汰,像這種key后期命中的概率也最低,所以將其淘汰。 

到此這篇關(guān)于Redis過期Key刪除策略和內(nèi)存淘汰策略的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Redis過期Key刪除策略和內(nèi)存淘汰策略內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用redis管理用戶登錄會話的方法

    使用redis管理用戶登錄會話的方法

    今天小編就為大家分享一篇使用redis管理用戶登錄會話的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Redis實(shí)現(xiàn)限流功能的幾種方法總結(jié)

    Redis實(shí)現(xiàn)限流功能的幾種方法總結(jié)

    在實(shí)際業(yè)務(wù)場景中,限流是保護(hù)系統(tǒng)的重要手段:在一段時(shí)間(period)內(nèi),限定某個(gè)行為(action)的最大次數(shù)(max_count),本文介紹如何基于 Redis 實(shí)現(xiàn)多種限流方案,需要的朋友可以參考下
    2026-05-05
  • dubbo服務(wù)使用redis注冊中心的系列異常解決

    dubbo服務(wù)使用redis注冊中心的系列異常解決

    這篇文章主要為大家介紹了dubbo服務(wù)在使用redis注冊中心遇到的一系列異常的解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • Redis中ZSet數(shù)據(jù)結(jié)構(gòu)與滑動窗口應(yīng)用實(shí)現(xiàn)

    Redis中ZSet數(shù)據(jù)結(jié)構(gòu)與滑動窗口應(yīng)用實(shí)現(xiàn)

    Redis?ZSET融合哈希表與跳躍表,支持O(1)成員查詢和O(logN)排序,適用于排行榜及滑動時(shí)間窗口限流,下面就來介紹一下Redis中ZSet數(shù)據(jù)結(jié)構(gòu)與滑動窗口應(yīng)用,感興趣的可以了解一下
    2025-07-07
  • Redis實(shí)現(xiàn)全局唯一id的使用示例

    Redis實(shí)現(xiàn)全局唯一id的使用示例

    全局ID生成器,是一種在分布式系統(tǒng)下用來生成全局唯一ID的工具,本文主要介紹了Redis實(shí)現(xiàn)全局唯一id的使用示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • Redis高并發(fā)問題的解決方法

    Redis高并發(fā)問題的解決方法

    這篇文章主要介紹了Redis高并發(fā)問題的解決辦法,具有很好的參考價(jià)值,感興趣的小伙伴們可以參考一下,具體如下:
    2018-05-05
  • 深入解析RedisJSON之如何在Redis中直接處理JSON數(shù)據(jù)

    深入解析RedisJSON之如何在Redis中直接處理JSON數(shù)據(jù)

    JSON已經(jīng)成為現(xiàn)代應(yīng)用程序之間數(shù)據(jù)傳輸?shù)耐ㄓ酶袷?然而,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫在處理JSON數(shù)據(jù)時(shí)可能會遇到性能瓶頸,本文將詳細(xì)介紹RedisJSON的工作原理、關(guān)鍵操作、性能優(yōu)勢以及使用場景,感興趣的朋友一起看看吧
    2024-05-05
  • redis如何清理緩存

    redis如何清理緩存

    本文主要介紹了redis如何清理緩存,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • redis延時(shí)隊(duì)列的項(xiàng)目實(shí)踐

    redis延時(shí)隊(duì)列的項(xiàng)目實(shí)踐

    本文主要介紹了redis延時(shí)隊(duì)列的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • redis慢查詢?nèi)罩镜脑L問和管理方式

    redis慢查詢?nèi)罩镜脑L問和管理方式

    這篇文章主要介紹了redis慢查詢?nèi)罩镜脑L問和管理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12

最新評論

宁远县| 乐平市| 旬邑县| 洪泽县| 临湘市| 宣汉县| 甘肃省| 金寨县| 瑞金市| 安图县| 侯马市| 原平市| 永德县| 小金县| 雅江县| 东宁县| 富平县| 淮北市| 赞皇县| 崇左市| 梨树县| 柯坪县| 邹平县| 定西市| 余干县| 永济市| 谢通门县| 彭阳县| 平武县| 南康市| 岑巩县| 普兰店市| 林芝县| 东乌珠穆沁旗| 巩义市| 和静县| 修水县| 田阳县| 九龙城区| 屏山县| 静宁县|