(一)Redis的入門介紹

什么是Redis坯钦?

??官方文檔解釋:Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.

??翻譯:Redis是一個(gè)開源(BSD許可)网棍,內(nèi)存數(shù)據(jù)結(jié)構(gòu)存儲(chǔ),用作數(shù)據(jù)庫(kù)屈芜,緩存和消息代理。它支持?jǐn)?shù)據(jù)結(jié)構(gòu),如字符串,散列笙蒙,列表,集合庆锦,帶有范圍查詢的排序集捅位,位圖,超級(jí)日志搂抒,具有半徑查詢和流的地理空間索引艇搀。Redis具有內(nèi)置復(fù)制,Lua腳本求晶,LRU回收焰雕,事務(wù)和不同級(jí)別的磁盤持久性,同時(shí)通過Redis Sentinel提供高可用性誉帅,通過Redis Cluster提供自動(dòng)分區(qū)淀散。

redis官網(wǎng) ??redis中文網(wǎng)

特點(diǎn)

  • Redis基于內(nèi)存右莱,并支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤中档插,重啟的時(shí)候可以再次加載進(jìn)行使用慢蜓。
  • Redis不僅僅支持簡(jiǎn)單的key-value類型的數(shù)據(jù),同時(shí)還提供list郭膛,set晨抡,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)则剃。
  • Redis支持?jǐn)?shù)據(jù)的備份耘柱,即master-slave模式的數(shù)據(jù)備份。

優(yōu)勢(shì)

  • 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 棍现。
  • 豐富的數(shù)據(jù)類型 – Redis支持二進(jìn)制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數(shù)據(jù)類型操作调煎。
  • 原子 – Redis的所有操作都是原子性的,同時(shí)Redis還支持對(duì)幾個(gè)操作全并后的原子性執(zhí)行己肮。
  • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性士袄。

應(yīng)用場(chǎng)景

??Redis可以在很多場(chǎng)景下使用,如緩存-熱數(shù)據(jù)谎僻、計(jì)數(shù)器娄柳、消息隊(duì)列、排行榜艘绍、秒殺系統(tǒng)赤拒、驗(yàn)證碼、分布式鎖等等具體場(chǎng)景诱鞠。

Redis安裝與驗(yàn)證

??mac系統(tǒng)直接使用brew install redis安裝即可(需先安裝Homebrew)挎挖,環(huán)境變量Homebrew會(huì)自動(dòng)配置,Redis配置文件redis.conf存放在/usr/local/ect/redis.conf般甲。如果是windows系統(tǒng)請(qǐng)使用虛擬機(jī)安裝Linux在安裝Redis肋乍,具體請(qǐng)參考Redis中文官網(wǎng)安裝教程

啟動(dòng) Redis

$redis-server

查看 redis 是否啟動(dòng):

$redis-cli

以上命令將打開以下終端:

redis 127.0.0.1:6379>

127.0.0.1 是本機(jī) IP ,6379 是 redis 服務(wù)端口》蟠妫現(xiàn)在我們輸入 PING 命令墓造。

redis 127.0.0.1:6379> ping
PONG

以上說明我們已經(jīng)成功安裝了redis。

Redis配置文件

??Redis 的配置文件位于 Redis 安裝目錄下锚烦,文件名為 redis.conf,我們可以修改該文件內(nèi)容進(jìn)行自定義配置觅闽,之后需要根據(jù)該配置文件啟動(dòng)Redis,此處只介紹幾個(gè)常用的配置:

  • bind 127.0.0.1 ::1:默認(rèn)情況下該配置只能接受本機(jī)的訪問請(qǐng)求涮俄,不寫的情況下蛉拙,無(wú)限制接受任何ip地址的訪問(測(cè)試階段使用#注釋掉即可),生產(chǎn)環(huán)境請(qǐng)寫你應(yīng)用服務(wù)器的地址彻亲。如果開啟了protected-mode且沒有設(shè)置密碼孕锄,則Redis只接受本機(jī)訪問吮廉。
  • protected-mode yes:保護(hù)模式,開啟時(shí)需要設(shè)置bind ip或者密碼畸肆。關(guān)閉時(shí)外部ip可以直接訪問宦芦。
  • port 6379:Redis服務(wù)端口號(hào)
  • daemonize no:Redis默認(rèn)不是以守護(hù)進(jìn)程(不會(huì)常駐后臺(tái))的方式運(yùn)行,可以通過該配置項(xiàng)修改轴脐,使用yes啟用守護(hù)進(jìn)程(常駐后臺(tái))
  • tcp-backlog 511:等待最大隊(duì)列數(shù)调卑,此處設(shè)置無(wú)效,默認(rèn)為128大咱,需要修改另一處配置文件
  • timeout 0:一個(gè)空閑的客戶端維持多少秒會(huì)關(guān)閉恬涧,0為永不關(guān)閉
  • tcp-keepalive 300:對(duì)訪問客戶端的心跳檢測(cè),每隔300秒檢測(cè)一次
  • pidfile:當(dāng)Redis以守護(hù)進(jìn)程方式運(yùn)行時(shí)碴巾,Redis默認(rèn)會(huì)把pid寫入/var/run/redis.pid文件溯捆,可以通過pidfile指定

Redis基本命令

??Redis命令大小寫均可,可是作為中國(guó)人餐抢,總覺得大寫有點(diǎn)變扭现使,無(wú)法像看簡(jiǎn)體繁體一樣直接理解其意低匙,所以個(gè)人習(xí)慣使用小寫旷痕。下面為基本的Redis命令:

  • redis-server [redis.conf]:開啟Redis服務(wù)器(可選擇以指定配置啟動(dòng))
  • redis-cli:?jiǎn)?dòng)客戶端連接本地Redis服務(wù)器
  • redis-cli -h <host> -p <port> -a <password>:?jiǎn)?dòng)客戶端連接遠(yuǎn)程Redis服務(wù)器(指定服務(wù)器IP端口和密碼)
  • ping:連接服務(wù)器后使用該命令用于檢測(cè) redis 服務(wù)是否啟動(dòng)(返回PONG)
  • select <index>:選擇某個(gè)庫(kù)
  • keys *:查詢當(dāng)前庫(kù)的所有鍵,*可以使用其他通配符代替顽冶。
  • exitsts <key>:判斷某個(gè)鍵是否存在
  • type <key>:判斷鍵的類型
  • del <key>:刪除某個(gè)鍵
  • expire <key> <second>:為鍵值設(shè)置過期(刪除)時(shí)間欺抗,單位秒
  • ttl <key>:查看還有多少秒過期,-1表示永不過期强重,-2表示已過期
  • dbsize:查看當(dāng)前數(shù)據(jù)庫(kù)的key的數(shù)量
  • flushdb:清空當(dāng)前庫(kù)
  • flushall:通殺全部庫(kù)

Redis的數(shù)據(jù)類型

??Redis支持的數(shù)據(jù)類型可以分為五大類:String類型绞呈、List類型、Set(無(wú)序集合)類型间景、Sorted Set(有序集合)類型佃声、Hash類型,Redis并沒有直接使用這些數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)鍵值對(duì)數(shù)據(jù)庫(kù)倘要,而是基于它們創(chuàng)建了一個(gè)對(duì)象系統(tǒng)圾亏,這些系統(tǒng)包含字符串對(duì)象、列表對(duì)象封拧、哈希對(duì)象志鹃、集合對(duì)象和有序集合對(duì)象,下面為具體介紹:

String類型

??String是Redis最基本的類型泽西,一個(gè)key對(duì)應(yīng)一個(gè)value,該類型是二進(jìn)制安全的曹铃,所以可以包含任何數(shù)據(jù),比如jpg圖片或者序列化的對(duì)象捧杉;一個(gè)Redis中字符串value最多可以是512M陕见,下面為該類型命令:

  • get <key>:獲取指定鍵的值

  • set <key> <value>:設(shè)置鍵與值

  • append <key> <value>:追加指定值到原值末尾

  • strlen <key>:獲取鍵的長(zhǎng)度

  • setnx <key> <value>:設(shè)置完鍵值后不可被覆蓋

  • incr <key>:將key中存儲(chǔ)的數(shù)字值加1秘血,只能對(duì)數(shù)字值操作

  • decr <key>:將key中存儲(chǔ)的數(shù)字值減1,只能對(duì)數(shù)字值操作

  • incrby/decrby <key> <步長(zhǎng)>:將key中存儲(chǔ)的數(shù)字加/減指定步長(zhǎng)

  • mset <key1> <value1> <key2> <value2>:同時(shí)設(shè)置多個(gè)鍵值對(duì)

  • mget <key1> <value1> <key2> <value2>:同時(shí)獲取多個(gè)鍵值對(duì)

  • msetnx <key1> <value1> <key2> <value2>:同時(shí)設(shè)置多個(gè)鍵值對(duì)评甜,不可被覆蓋

  • get range <key> <起始位置> <結(jié)束位置>:獲得值的范圍直撤,類似java的substring

  • setrange <key> <起始位置> value:從起始位置以value值代替

  • setex <key> <過期時(shí)間> <value>:設(shè)置鍵值的同時(shí),設(shè)置過期時(shí)間蜕着,單位秒

  • psetex <key> <過期時(shí)間> <value>:這個(gè)命令和setex命令相似谋竖,但它以毫秒為單位設(shè)置 key 的生存時(shí)間,而不是像 setex 命令那樣承匣,以秒為單位蓖乘。

  • getset <key> <value>:以新?lián)Q舊,設(shè)置新值同時(shí)獲得新值

List類型

??單鍵多值韧骗,Redis列表(List)是簡(jiǎn)單的字符串列表嘉抒,按照插入順序排序。你可以添加一個(gè)元素導(dǎo)列表的頭部(左邊)或者尾部(右邊)袍暴;它的底層是雙向鏈表些侍,對(duì)兩端的操作性能很高,通過索引下標(biāo)的操作中間的節(jié)點(diǎn)性能會(huì)變差政模;一個(gè)列表最多可以包含 232 - 1 個(gè)元素 (4294967295, 每個(gè)列表超過40億個(gè)元素)岗宣。

  • lpush/rpush <key> <value1> <value2>:從左邊/右邊插入一個(gè)或多個(gè)值到列表頭部
  • lpop/rpop <key>:從左邊/右邊吐出一個(gè)值,值在鍵在淋样,值空鍵亡
  • rpoplpush <key1> <key2>:從<key1>列表右邊吐出一個(gè)值耗式,插到<key2>列表右邊
  • lrange <key> <start> <end>:按照索引下標(biāo)獲得元素(從左到右)
  • lindex <key> <index>:按照索引下標(biāo)獲得元素(從左到右)
  • llen <key>:獲得列表長(zhǎng)度
  • linsert <key> before/after <pivot> <value>:在指定列表的指定值前面或后面插入新值
  • lrem <key> <n> <value>:刪除n個(gè)value(可以有多個(gè)相同的value,n為正數(shù)代表從左邊刪除趁猴,負(fù)數(shù)則從右邊刊咳,0代表刪除所有 )

Set類型

??Redis的Set是string類型的無(wú)序集合。集合成員是唯一的儡司,這就意味著集合中不能出現(xiàn)重復(fù)的數(shù)據(jù)娱挨。Redis 中 集合是通過哈希表實(shí)現(xiàn)的,所以添加捕犬,刪除跷坝,查找的復(fù)雜度都是O(1)。集合中最大的成員數(shù)為 232 - 1 (4294967295, 每個(gè)集合可存儲(chǔ)40多億個(gè)成員)或听。

  • sadd <key> <member1> <member2>:向集合添加一個(gè)或多個(gè)成員探孝,重復(fù)成員將被省略
  • smembers <key>:查看集合中的所有成員
  • sismember <key> <member>:判斷member元素是否為集合中的內(nèi)容,有返回1,無(wú)返回0
  • scard <key>:返回該集合的個(gè)數(shù)
  • srem <key> <member1> <member2>:刪除集合中的成員誉裆,可同時(shí)刪除多個(gè)
  • spop <key>:隨機(jī)吐出集合中的一個(gè)成員并顯示
  • srandmember <key> <n>:隨機(jī)從該集合中取出n個(gè)值顿颅,不會(huì)從集合中刪除
  • sinter <key1> <key2>:返回兩個(gè)集合的交集
  • sunion <keyl> <key2>:返回兩個(gè)集合的并集
  • sdiff <key1> <key2>:返回兩個(gè)集合的差集,集合先后順序不同結(jié)果不同

Sorted Set類型(有序集合)

??Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重復(fù)的成員。不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù)(score)足丢。redis正是通過分?jǐn)?shù)來(lái)為集合中的成員進(jìn)行從小到大的排序粱腻。有序集合的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)庇配。集合是通過哈希表實(shí)現(xiàn)的,所以添加绍些,刪除捞慌,查找的復(fù)雜度都是O(1)。 集合中最大的成員數(shù)為 232 - 1 (4294967295, 每個(gè)集合可存儲(chǔ)40多億個(gè)成員)柬批。

  • zadd <key> <score1> <member1> <score2> <member2>:向有序集合按分?jǐn)?shù)添加一個(gè)或多個(gè)成員啸澡,或者更新已存在成員的分?jǐn)?shù)
  • zrange key <start> <stop> [withscores]:通過索引區(qū)間返回有序集合成指定區(qū)間內(nèi)的成員(可選顯示分?jǐn)?shù))
  • zrangebyscore key min max [withscores]:通過分?jǐn)?shù)從小到大返回有序集合指定區(qū)間內(nèi)的成員
  • zrevrangebyscore key max min [withscores]:通過分?jǐn)?shù)從大到小返回有序集合指定區(qū)間內(nèi)的成員
  • zincrby <key> <increment> <member>:有序集合中對(duì)指定成員的分?jǐn)?shù)加上增量 increment
  • zrem <key> <member1> <member2>:移除有序集合中的一個(gè)或多個(gè)成員
  • zcount <key> <min> <max>:計(jì)算在有序集合中指定區(qū)間分?jǐn)?shù)的成員數(shù)
  • zrank <key> <member>:返回有序集合中指定成員的索引排名

Hash類型

??Redis hash 是一個(gè)string類型的field和value的映射表,類似于Java里面的Map<String,Object>氮帐,hash特別適合用于存儲(chǔ)對(duì)象嗅虏。Redis 中每個(gè) hash 可以存儲(chǔ) 232 - 1 鍵值對(duì)(40多億)。

  • hset key <field> <value>:將哈希表 key 中的字段 field 的值設(shè)為 value
  • hget key <field>:獲取存儲(chǔ)在哈希表中指定字段的值
  • hmset key <field1> <value1> <fields2> <value2>:同時(shí)將多個(gè) field-value (域-值)對(duì)設(shè)置到哈希表 key 中
  • hexists key <field>:查看哈希表key中上沐,給定field是否存在
  • hkeys <key>:列出該哈希表中所有的field
  • hincrby <key> <field>:為哈希表key中的field的值加上增量
  • hsetnx <key> <field> <value>:為哈希表key追加一個(gè)field字段皮服,其值設(shè)置為value,僅當(dāng)field不存在時(shí)

Java客戶端Jedis連接Redis服務(wù)器

??要想通過Java連接Redis参咙,需要使用Jedis包龄广,Jedis所需的jar包為Jedis.jar,請(qǐng)去maven倉(cāng)庫(kù)自行下載你想要的jar版本蕴侧,當(dāng)我們通過maven構(gòu)建項(xiàng)目之后择同,加入上述包的依賴即可,下面為測(cè)試代碼:

import ...
public class JedisTest {
    Jedis jedis = new Jedis("127.0.0.1",6379);

    @Before
    public void before(){
        jedis.select(6);
        jedis.flushDB();
    }

    @Test
    public void test1(){
        jedis.zadd("user",200.0,"jack");

        Map<String,Double> map = new HashMap<>();
        map.put("tom",100.0);
        map.put("lucy",400.0);
        map.put("william",300.0);
        jedis.zadd("username",map);
    }
}

??此處和當(dāng)前主機(jī)的6379端口連接(因?yàn)閙ac系統(tǒng)自帶終端戈盈,如果是windows系統(tǒng)請(qǐng)輸入虛擬機(jī)中服務(wù)器IP地址奠衔,且需要先將防火墻關(guān)閉,修改redis.conf配置文件:注釋bing 127.0.0.1,protected-mode 改為 no,daemonize改為yes塘娶,然后通過reds-server /usr/local/etc/redis.conf啟動(dòng)Redis服務(wù)器)。當(dāng)我們執(zhí)行測(cè)試時(shí)痊夭,先執(zhí)行@Before里語(yǔ)句刁岸,即選擇了索引為6的庫(kù),之后清空了該庫(kù)所有數(shù)據(jù)她我。當(dāng)我們執(zhí)行test1測(cè)試虹曙,會(huì)往有序集合加入分?jǐn)?shù)為200的成員jack,后續(xù)我們創(chuàng)建一個(gè)Map集合加入相應(yīng)數(shù)據(jù)番舆,在將該集合加入有序集合username中酝碳,我們可以直接在Redis服務(wù)器查看到添加的數(shù)據(jù):

127.0.0.1:6379[6]]> zrange username 0 -1 withscores
1)  "tom"
2)  "100"
3)  "william"
4)  "300"
5)  "lucy"
6)  "400"
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市恨狈,隨后出現(xiàn)的幾起案子疏哗,更是在濱河造成了極大的恐慌,老刑警劉巖禾怠,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件返奉,死亡現(xiàn)場(chǎng)離奇詭異贝搁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)芽偏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門雷逆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人污尉,你說我怎么就攤上這事膀哲。” “怎么了被碗?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵等太,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我蛮放,道長(zhǎng)缩抡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任包颁,我火速辦了婚禮瞻想,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘娩嚼。我一直安慰自己蘑险,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布岳悟。 她就那樣靜靜地躺著佃迄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贵少。 梳的紋絲不亂的頭發(fā)上呵俏,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音滔灶,去河邊找鬼普碎。 笑死,一個(gè)胖子當(dāng)著我的面吹牛录平,可吹牛的內(nèi)容都是我干的麻车。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼斗这,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼动猬!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起表箭,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赁咙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體序目,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡臂痕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猿涨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片握童。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖叛赚,靈堂內(nèi)的尸體忽然破棺而出澡绩,到底是詐尸還是另有隱情,我是刑警寧澤俺附,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布肥卡,位于F島的核電站,受9級(jí)特大地震影響事镣,放射性物質(zhì)發(fā)生泄漏步鉴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一璃哟、第九天 我趴在偏房一處隱蔽的房頂上張望氛琢。 院中可真熱鬧,春花似錦随闪、人聲如沸阳似。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)撮奏。三九已至,卻和暖如春当宴,著一層夾襖步出監(jiān)牢的瞬間畜吊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工即供, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留定拟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓逗嫡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親株依。 傳聞我的和親對(duì)象是個(gè)殘疾皇子驱证,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 南日島是福建省一個(gè)美麗的小島,約有52平方千米恋腕,比南澳島小了一半抹锄。 南日島每天靠四只渡船與大陸連接,排隊(duì)上船的汽車...
    a33203716fe7閱讀 912評(píng)論 0 0
  • 鄰居家阿姨涮拖把回店賣瓶水的功夫,拖把凍在樹上了伙单。 冷 冷 冷 冷的讓人心煩获高!零下8度! 今天班主任發(fā)到群...
    Givemeone閱讀 230評(píng)論 0 0
  • 看云卷云舒 只是隨風(fēng)流動(dòng) 點(diǎn)點(diǎn)殘陽(yáng)斜掛西天 卻染紅了半邊天 有一滴殘淚滑落眼角 留下一絲遺憾 你說 夕陽(yáng)西下是最美...
    播音1801范文軒閱讀 142評(píng)論 0 0
  • 習(xí)家池吻育,又名高陽(yáng)池念秧,位于湖北襄陽(yáng)城南約五公里的鳳凰山南麓,是東漢初年襄陽(yáng)侯習(xí)郁的私家園林布疼,延存至今已有近2000年...
    行走的鹿閱讀 1,001評(píng)論 4 13