java操作redis1


1、為什么要用NOSQL

NOSQL(NoSQL = Not Only SQL),意即“不僅僅是SQL”,是一項全新的數據庫理念,泛指非關系型的數據庫

​ 隨着互聯網的高速崛起,網站的用戶群的增加,訪問量的上升,傳統(關系型)數據庫上都開始出現了性能瓶頸,web程序不再僅僅專注在功能上,同時也在追求性能。所以NOSQL數據庫應運而上,具體表現為對如下三高問題的解決:

  • High performance - 對數據庫高並發讀寫的需求

    ​ web2.0網站要根據用戶個性化信息來實時生成動態頁面和提供動態信息,所以基本上無法使用動態頁面靜態化技術,因此數據庫並發負載非常高,往往要達到每秒上萬次讀寫請求。關系數據庫應付上萬次SQL查詢還勉強頂得住,但是應付上萬次SQL寫數據請求,硬盤IO就已經無法承受了。其實對於普通的BBS網站,往往也存在對高並發寫請求的需求,例如網站的實時統計在線用戶狀態,記錄熱門帖子的點擊次數,投票計數等,因此這是一個相當普遍的需求。

  • Huge Storage - 對海量數據的高效率存儲和訪問的需求

    ​ 類似Facebook,twitter,Friendfeed這樣的SNS網站,每天用戶產生海量的用戶動態,以Friendfeed為例,一個月就達到了2.5億條用戶動態,對於關系數據庫來說,在一張2.5億條記錄的表里面進行SQL查詢,效率是極其低下乃至不可忍受的。再例如大型web網站的用戶登錄系統,例如騰訊,盛大,動輒數以億計的帳號,關系數據庫也很難應付。

  • High Scalability && High Availability- 對數據庫的高可擴展性和高可用性的需求

    ​ 在基於web的架構當中,數據庫是最難進行橫向擴展的,當一個應用系統的用戶量和訪問量與日俱增的時候,你的數據庫卻沒有辦法像web server和app server那樣簡單的通過添加更多的硬件和服務節點來擴展性能和負載能力。對於很多需要提供24小時不間斷服務的網站來說,對數據庫系統進行升級和擴展是非常痛苦的事情,往往需要停機維護和數據遷移,為什么數據庫不能通過不斷的添加服務器節點來實現擴展呢?

2、NOSQL特點

​ 在大數據存取上具備關系型數據庫無法比擬的性能優勢,例如:

  • 易擴展

    ​ NoSQL數據庫種類繁多,但是一個共同的特點都是去掉關系數據庫的關系型特性。數據之間無關系,這樣就非常容易擴展。也無形之間,在架構的層面上帶來了可擴展的能力。

  • 大數據量,高性能

    NoSQL數據庫都具有非常高的讀寫性能,尤其在大數據量下,同樣表現優秀。這得益於它的無關系性,數據庫的結構簡單。

  • 靈活的數據模型

    ​ NoSQL無需事先為要存儲的數據建立字段,隨時可以存儲自定義的數據格式。而在關系數據庫里,增刪字段是一件非常麻煩的事情。如果是非常大數據量的表,增加字段簡直就是一個噩夢。這點在大數據量的Web2.0時代尤其明顯。

  • 高可用

    ​ NoSQL在不太影響性能的情況,就可以方便的實現高可用的架構。比如Cassandra,HBase模型,通過復制模型也能實現高可用。

3、redis特點

3.1.什么是Redis

​ Redis是用C語言開發的一個開源的高性能鍵值對(key-value)數據庫數據是保存在內存里面的. 官方提供測試數據,50個並發執行100000個請求,讀的速度是110000次/s,寫的速度是81000次/s ,且Redis通過提供多種鍵值數據類型來適應不同場景下的存儲需求,目前為止Redis支持的鍵值數據類型如下:

  • 字符串類型 string
  • 散列類型 hash
  • 列表類型 list
  • 集合類型 set
  • 有序集合類型 sortedset

3.2 redis的應用場景

  • 緩存(數據查詢、短連接、新聞內容、商品內容等等)
  • 任務隊列。(秒殺、搶購、12306等等)
  • 數據過期處理(可以精確到毫秒, 短信驗證碼)
  • 分布式集群架構中的session分離 session 服務器里面
  • 聊天室的在線好友列表
  • 應用排行榜
  • 網站訪問統計

4、Linux環境下安裝

  1. 在虛擬機中安裝c++環境
yum -y install gcc-c++
  1. 下載Redis
  2. 上傳到Linux
  3. 解壓
tar -zxf redis-4.0.14.tar.gz
  1. 編譯
cd redis-4.0.14
make
  1. 安裝
make install PREFIX=/usr/local/redis
  1. 進入安裝好的redis目錄,復制配置文件
cd /usr/local/redis/bin
cp /root/redis-4.0.14/redis.conf ./
  1. 修改配置文件
# 修改配置文件
vi redis.conf
# Redis后台啟動
修改 daemonize 為 yes
# Redis服務器可以跨網絡訪問 
修改 bind 為 0.0.0.0
# 開啟aof持久化
appendonly yes
  1. 啟動redis
./redis-server redis.conf

5、Linux命令操作

5.0、通用命令

1、基礎命令
  • keys *: 查詢所有的key

  • exists key:判斷是否有指定的key 若有返回1,否則返回0

  • expire key 秒數:設置這個key在緩存中的存活時間

  • ttl key:展示指定key的剩余時間

    ​ 若返回值為 -1:永不過期

    ​ 若返回值為 -2:已過期或者不存在

  • del key:刪除指定key

  • rename key 新key:重命名

  • type key:判斷一個key的類型

  • ping :測試連接是否連接

2、分庫命令

​ redis默認是16個數據庫, 編號是從0~15. 【默認是0號庫】

  • select index:切換庫
  • move key index: 把key移動到幾號庫(index是庫的編號)
  • flushdb:清空當前數據庫
  • flushall:清空當前實例下所有的數據庫

5.1、string字符串類型

1、概述

string是redis最基本的類型,用的也是最多的,一個key對應一個value。 一個鍵最大能存儲512MB.

2、應用場景
  1. 緩存功能:字符串最經典的使用場景,redis最為緩存層,Mysql作為儲存層,絕大部分請求數據都是在redis中操作,由於redis具有支撐高並發特性,所以緩存通常能起到加速讀寫和降低 后端壓力的作用。
  2. 計數器功能:比如視頻播放次數,點贊次數。
  3. ID遞增
3、對應常見命令API
命令 描述
SET key value 設置指定 key 的值
GET key 獲取指定 key 的值
DEL key 刪除key
GETSET key value 將給定 key 的值設為 value ,並返回 key 的舊值(old value)。
SETEX key seconds value 將值 value 關聯到 key ,並將 key 的過期時間設為 seconds (以秒為單位)。
SETNX key value 只有在 key 不存在時設置 key 的值。
INCR key 將 key 中儲存的數字值增一。
INCRBY key increment 將 key 所儲存的值加上給定的增量值(increment) 。
DECR key 將 key 中儲存的數字值減一。
DECRBY key decrement key 所儲存的值減去給定的減量值(decrement) 。
4、問題

​ 假設有User對象以JSON序列化的形式存儲到Redis中,User對象有id,username、password、age、name等屬性,存儲的過程如下: 保存、更新: User對象 ==> json(string) ==>redis

​ 如果在業務上只是更新age屬性,其他的屬性並不做更新我應該怎么做呢? 如果仍然采用上邊的方法在傳輸、處理時會造成資源浪費,下邊講的hash可以很好的解決這個問題

5.2、哈希(hash)類型

1、概述

​ Redis中hash 是一個鍵值對集合。

​ Redis hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象。

​ Redis存儲hash可以看成是String key 和String value的map容器. 也就是說把值看成map集合.

​ 它它特別適合存儲對象相比較而言,將一個對象類型存儲在Hash類型里要比存儲在String類型里占用更少的內存空間並方便存取整個對象

2、應用場景

用一個對象來存儲用戶信息,商品信息,訂單信息等等。

存儲商品信息

  • 商品字段【商品id、商品名稱、商品價格】
  • 定義商品信息的key, 商品1001的信息在 Redis中的key為:[items:1001]
  • 存儲商品信息
3、常見命令
命令 命令描述
hset key filed value 將哈希表 key 中的字段 field 的值設為 value
hmset key field1 value1 [field2 value2]... 同時將多個 field-value (字段-值)對設置到哈希表 key 中
hget key filed 獲取存儲在哈希表中指定字段的值
hmget key filed1 filed2 獲取多個給定字段的值
hdel key filed1 [filed2] 刪除一個或多個哈希表字段
hlen key 獲取哈希表中字段的數量
del key 刪除整個hash(對象)
HGETALL key 獲取在哈希表中指定 key 的所有字段和值
HKEYS key 獲取所有哈希表中的字段
HVALS key 獲取哈希表中所有值

5.3、list類型

1、概述

列表類型(list)可以存儲一個有序的字符串列表(鏈表),常用的操作是向列表兩端添加元素,或者獲得列表的某一個片段。
列表類型內部是使用雙向鏈表(double linked list)實現的,所以向列表兩端添加元素的時間復雜度為0(1),獲取越接近兩端的元素速度就越快。這意味着即使是一個有幾千萬個元素的列表,獲取頭部或尾部的10條記錄也是極快的。

2、應用場景

如好友列表,粉絲列表,消息隊列,最新消息排行等。

rpush方法就相當於將消息放入到隊列中,lpop/rpop就相當於從隊列中拿去消息進行消費

例子: 在Redis中創建商品評論列表,用戶發布商品評論,將評論信息轉成json存儲到list中。用戶在頁面查詢評論列表,從redis中取出json數據展示到頁面。

3、常見命令

命令 命令描述
lpush key value1 value2... 將一個或多個值插入到列表頭部(左邊)
rpush key value1 value2... 在列表中添加一個或多個值(右邊)
lpop key 左邊彈出一個 相當於移除第一個
rpop key 右邊彈出一個 相當於移除最后一個
llen key 返回指定key所對應的list中元素個數
LINDEX key index 通過索引獲取列表中的元素
LINSERT key BEFORE| AFTER pivot value 在列表的元素前或者后插入元素

5.4、set集合類型

1、概述

Redis的Set是string類型的無序集合。集合成員是唯一的,這就意味着集合中不能出現重復的數據。

Redis 中 集合是通過哈希表實現的,所以添加,刪除,查找的時間復雜度都是O(1)。集合中最大的成員數為 2的32次方 -1 (4294967295, 每個集合可存儲40多億個成員)。

​ Redis還提供了多個集合之間的交集、並集、差集的運算

​ 特點:無序+唯一

2、應用場景

​ 投票記錄

​ 共同好友、共同興趣、分類標簽

3、常見命令

命令 命令描述
sadd key member1 [member2] 向集合添加一個或多個成員
srem key member1 [member2] 移除一個成員或者多個成員
smembers key 返回集合中的所有成員,查看所有
SCARD key 獲取集合的成員數
SPOP key 移除並返回集合中的一個隨機元素
SDIFF key1 [key2] 返回給定所有集合的差集
SUNION key1 [key2] 返回所有給定集合的並集
SINTER key1 [key2] 返回給定所有集合的交集

4、應用舉例

共同好友

  • A的好友
  • B的好友
  • A和B的共同好友

5.5、有序集合(sorted set)類型

1、概述

Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重復的成員。

不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。

有序集合的成員是唯一的,但分數(score)卻可以重復。

集合是通過哈希表實現的,所以添加,刪除,查找的復雜度都是O(1)。 集合中最大的成員數為 232 - 1 (4294967295, 每個集合可存儲40多億個成員)。

特點: 有序(根據分數排序)+唯一

2、應用場景

排行榜:例如視頻網站需要對用戶上傳的視頻做排行榜.

3、常見命令

命令 命令描述
ZADD key score member [score member ...] 增加元素
ZSCORE key member 獲取元素的分數
ZREM key member [member ...] 刪除元素
ZCARD key 獲得集合中元素的數量
ZRANGE key start stop[WITHSCORES] 獲得排名在某個范圍的元素列表

4、應用舉例

商品銷售排行榜

  • 需求:根據商品銷售量對商品進行排行顯示
  • 思路:定義商品銷售排行榜(sorted set集合),Key為items:sellsort,分數為商品銷售量
  • 實現
--商品編號1001的銷量是9,商品編號1002的銷量是10
ZADD items:sellsort 9 1001 10 1002		

--商品編號1001的銷量加1
ZINCRBY items:sellsort 1 1001

--商品銷量前10名
ZRANGE items:sellsort -1 -9 withscores

6、java操作redis

1、簡單介紹

Jedis就是使用Java操作Redis的客戶端(工具包)

利用java來操作redis,官方推薦的使用工具:jedis或者是redisson

2、常用方法使用API

方法 解釋
new Jedis(host, port) 創建jedis對象,參數host是redis服務器地址,參數port是redis服務端口
set(key,value) 設置字符串類型的數據
get(key) 獲得字符串類型的數據
hset(key,field,value) 設置哈希類型的數據
hget(key,field) 獲得哈希類型的數據
lpush(key,values) 設置列表類型的數據
lpop(key) 列表左面彈棧
rpop(key) 列表右面彈棧
sadd(String key, String... members) 設置set類型的數據
zrange(String key, long start, long end) 獲得在某個范圍的元素列表
del(key) 刪除key

3、使用java操作各種API

需求: 使用java代碼操作Redis 進行增(改)刪查

步驟:

  1. 導入jar
  2. 創建Jedis對象
  3. 使用方法操作
  4. 關閉資源
    @Test
    public void fun01() {
        //1. 創建Jedis對象
        String host = "127.0.0.1";
        int port = 6379;
        Jedis jedis = new Jedis(host, port);
        //2. 操作Redis

        //2.1 字符串
        jedis.set("akey", "你好");
        System.out.println(jedis.get("akey"));
        jedis.del("akey");

        //2.2hash
        Map<String,String> map = new HashMap<String, String>();
        map.put("name","zs");
        map.put("sex","男");
        map.put("age","18");
        jedis.hmset("u1",map);

        System.out.println(jedis.hget("u1", "name"));

        //2.3List
        jedis.rpush("l1","a","b","c","d","e","f");
        List<String> l1 = jedis.lrange("l1", 0, -1);
        System.out.println(l1);

        //2.4Set
        jedis.sadd("s1","a","b","c","d");
        jedis.sadd("s2","a","b","c","d","e","f");
        Set<String> set = jedis.sdiff("s2", "s1");
        for (String s : set) {
            System.out.println(s);
        }

        //3. 釋放資源
        jedis.close();

    }

4、jedis連接池

jedis連接資源的創建與銷毀是很消耗程序性能,所以jedis為我們提供了jedis的池化技術,jedisPool在創建時初始化一些連接資源存儲到連接池中,使用jedis連接資源時不需要創建,而是從連接池中獲取一個資源進行redis的操作,使用完畢后,不需要銷毀該jedis連接資源,而是將該資源歸還給連接池,供其他請求使用。

4.1、步驟

     @Test
	// 使用池子來獲得jedis jedis當做方便面 開工廠 張三 100個工人  李四
	public void fun01() {
		//0 創建池子配置對象
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		poolConfig.setMaxTotal(10);//設置最大連接數量(可以不配...)
		
		String host = "localhost";
		int port = 6379;
		//1. 創建Jedis池子對象
		JedisPool jedisPool = new JedisPool(poolConfig, host, port);
		
		//2. 從池子里面獲得jedis
		Jedis jedis = jedisPool.getResource();
		
		//3. 操作redis數據庫
		//3.1 存
		//jedis.set("ckey", "ccc");
		//3.2 取
		//System.out.println(jedis.get("ckey"));
		//3.3 刪除
		jedis.del("ckey");
		
		//4. 釋放
		jedis.close();
		jedisPool.close();	
	}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM