Redis的API應用

全局命令

   1,查看全部鍵:keys *   set school dongnao   set hello worldjava

   2,鍵總數 dbsize  //2個鍵,若是存在大量鍵,線上禁止使用此指令redis

   3,檢查鍵是否存在:exists key  //存在返回1,不存在返回0spring

   4,刪除鍵:del key  //del hello school, 返回刪除鍵個數,刪除不存在鍵返回0sql

   5,鍵過時:expire key seconds  //set name test  expire name 10 //10秒過時數據庫

                     ttl 查看剩餘的過時時間編程

   6,鍵的數據結構類型:type key //type hello  //返回string,鍵不存在返回none緩存

   7,flushall 清空全部數據 flushdb 清空當前庫數據,redis單機環境下有16個庫(0-15)網絡

單線程架構

 列舉例子:三個客戶端同時執行命令數據結構

         客戶端1:set name test架構

         客戶端2:incr num

         客戶端3:incr num

執行過程:發送指令-〉執行命令-〉返回結果

執行命令:單線程執行,全部命令進入隊列,按順序執行,使用I/O多路複用解決I/O問題,後面有介紹(因爲讀寫操做等待用戶輸入或輸出都是阻塞的,因此 I/O 操做在通常狀況下每每不能直接返回,這會致使某一文件的 I/O 阻塞致使整個進程沒法對其它客戶提供服務 ,IO多路複用模型是創建在內核提供的多路分離函數select基礎之上的,使用select函數能夠避免同步非阻塞IO模型中輪詢等待的問題)

單線程快緣由:純內存訪問, 非阻塞I/O(使用多路複用),單線程避免線程切換和競爭產生資源消耗

問題:若是某個命令執行,會形成其它命令的阻塞

字符串<String>

1,字符串類型:

實際上能夠是字符串(包括XML JSON),還有數字(整形 浮點數),二進制(圖片 音頻 視頻),最大不能超過512MB

2,設值命令:

set age 23 ex 10 //10秒後過時  px 10000 毫秒過時

setnx name test  //不存在鍵name時,返回1設置成功;存在的話失敗0

set age 25 xx    //存在鍵age時,返回1成功

場景:若是有多客戶同時執行setnx,只有一個能設置成功,可作分佈式鎖

3.獲值命令:

get age //存在則返回value, 不存在返回nil

4.批量設值:

mset country china city beijing

5.批量獲取:

mget country city address //返回china  beigjin, address爲nil

若沒有mget命令,則要執行n次get命令

使用mget=1次網絡請求+redis內部n次查詢

6.計數:

incr age //必須爲整數自加1,非整數返回錯誤,無age鍵從0自增返回1

decr age //整數age減1

incrby age 2 //整數age+2

decrby age 2//整數age -2

incrbyfloat score 1.1 //浮點型score+1.1

7.append追加指令:

set name hello; append name world //追加後成helloworld

8.字符串長度:

set hello 「世界」;strlen hello//結果6,每一箇中文佔3個字節

9.截取字符串:

set name helloworld ; getrange name 2 4//返回 llo

10.內部編碼:

int:            8字節長整理//set age 100; object encoding age //返回int

embstr:    小於等於39字節串set name bejin; object encodeing name//embstr

raw:          大於39字節的字符串set a fsdfwerwerweffffffffffdfs//返回raw

 

Ps: 

   Flushall清除全部數據  flushdb  清庫

   redis 單點環境下有16個庫   select 15 能夠切換到第15個數據庫 集羣只有一個數據庫0

應用場景

1.鍵值設計: 

業務名:對象名:id:[屬性],數據庫爲order, 用戶表user,對應的鍵可爲 order:user:1 或order:user:1:name

注意:

redis目前處於受保護模式,不容許非本地客戶端連接,能夠經過給redis設置密碼,而後客戶端連接的時候,寫上密碼就能夠了

127.0.0.1:6379> config set requirepass 123456  臨時生效

或者修改redis.conf   requirepass 123456,啓動時./redis-server redis.conf指定conf

./redis-cli -p 6379 -a 12345678  //須要加入密碼才能訪問

切換數據庫:

 select 2

 

場景實踐cache-demo

JedisAllCommandTest OrderListHashTest SiteVisitNumTest

 

操做工具

redis通用工具類

public class JedisUtils {

	private JedisPool pool = null;

	//具體使用見java代碼
}

jedis緩存工具類,使用redisTemlate處理

@Component
public class RedisUtil {

	// spring 對redis操做的封裝,使用了模板模式
	@Resource
	private RedisTemplate<String, Object> template;

}

Spring的配置

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxTotal" value="100" />
		<property name="maxIdle" value="10" />
	</bean>

	<bean id="jedisConnectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		destroy-method="destroy">
		<property name="hostName" value="192.168.1.111" />
		<property name="port" value="6379" />
		<property name="database" value="2" />
		<property name="timeout" value="3000" />
		<property name="usePool" value="true" />
		<property name="password" value="12345678"/>
		<property name="poolConfig" ref="jedisPoolConfig" />
	</bean>

	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="jedisConnectionFactory" />
		<property name="keySerializer" ref="stringRedisSerializer"/>
			 
		<property name="valueSerializer" ref="stringRedisSerializer"/>
		
		<property name="enableTransactionSupport" value="false"></property>
	</bean>
	
	
	
	<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
    <bean  id ="JdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>  
  
    <bean  id="GenericToStringSerializer" class="org.springframework.data.redis.serializer.GenericToStringSerializer"  
            c:type="java.lang.Long"/>  
	
	
    <cache:annotation-driven/>

	<!-- declare Redis Cache Manager -->
	<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
		<constructor-arg index="0" ref="redisTemplate"></constructor-arg>
	</bean>

 

哈希hash

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

命令  hset key field value

設值:hset user:1 name james         //成功返回1,失敗返回0

取值:hget user:1 name              //返回james

刪值:hdel user:1 age               //返回刪除的個數

計算個數:hset user:1 name james; hset user:1 age 23;

                hlen user:1               //返回2,user:1有兩個屬性值

批量設值:hmset user:2 name james age 23 sex boy //返回OK

批量取值:hmget user:2 name age sex   //返回三行:james 23 boy

判斷field是否存在:hexists user:2 name //若存在返回1,不存在返回0

獲取全部field: hkeys user:2            // 返回name age sex三個field

獲取user:2全部value:hvals user:2     // 返回james 23 boy

獲取user:2全部field與value:hgetall user:2 //name age sex james 23 boy值

增長1:hincrby user:2 age 1      //age+1

            hincrbyfloat user:2 age 2   //浮點型加2

內部編碼

      ziplist<壓縮列表>和hashtable<哈希表>

      當field個數少且沒有大的value時,內部編碼爲ziplist

      如:hmset user:3 name james age 24; object encoding user:3 //返回ziplist

      當value大於64字節,內部編碼由ziplist變成hashtable

      如:hset user:4 address 「fsgst64字節」; object encoding user:3 //返回hashtable

應用場景

    好比將關係型數據錶轉成redis存儲:

HASH類型是稀疏,每一個鍵能夠有不一樣的filed, 若用redis模擬作關係複雜查詢開發因難,維護成本高

三種方案實現用戶信息存儲優缺點

1.原生:

            set user:1:name james;

             set user:1:age  23;

             set user:1:sex boy;

      優勢:簡單直觀,每一個鍵對應一個值

      缺點:鍵數過多,佔用內存多,用戶信息過於分散,不用於生產環境

2.將對象序列化存入redis

            set user:1 serialize(userInfo);

      優勢:編程簡單,若使用序列化合理內存使用率高

      缺點:序列化與反序列化有必定開銷,更新屬性時須要把userInfo全取出來進行反序列化,更新後再序列化到redis

3.使用hash類型

             hmset user:1 name james age 23 sex boy

       優勢:簡單直觀,使用合理可減小內存空間消耗

       缺點:要控制ziplist與hashtable兩種編碼轉換,且hashtable會消耗更多內存

總結:對於更新很少的狀況下,可使用序列化,對於VALUE值不大於64字節可使用hash類型

 

列表 list

用來存儲多個有序的字符串,一個列表最多可存2的32次方減1個元素

由於有序,能夠經過索引下標獲取元素或某個範圍內元素列表,列表元素能夠重複

列表命令

添加命令

rpush james c b a //從右向左插入cba, 返回值3

lrange james 0 -1 //從左到右獲取列表全部元素 返回 c b a

lpush key c b a //從左向右插入cba

linsert james before b teacher //在b以前插入teacher, after爲以後,使用lrange james 0 -1 查看:c teacher b a

查找命令

lrange key start end //索引下標特色:從左到右爲0到N-1

lindex james -1 //返回最右末尾a,-2返回b

llen james    //返回當前列表長度

lpop james   //把最左邊的第一個元素c刪除

rpop james   //把最右邊的元素a刪除
 
lrem key count value//刪除指定元素

應用場景設計: cacheListHashApplicationTest用例

 每一個用戶有多個訂單key爲 order:1   order:2  order:3, 結合hmset

hmset order:1 orderId 1 money 36.6 time 2018-01-01

hmset order:2 orderId 2 money 38.6 time 2018-01-01

hmset order:3 orderId 3 money 39.6 time 2018-01-01

把訂單信息的key放到隊列

     lpush user:1:order order:1 order:2 order:3

每新產生一個訂單,

     hmset order:4 orderId 4 money 40.6 time 2018-01-01

追加一個order:4放入隊列第一個位置

    lpush user:1:order order:4

當須要查詢用戶訂單記錄時:

    List orderKeys = lrange user:1 0 -1 //查詢user:1 的全部訂單key值

   for(Order order: orderKeys){

           hmget order:1

    }

列表內部編碼:

1,當元素個數少且沒大元素,編碼爲ziplist,減小內存的使用

   rpush list a b c

   object encoding list //返回ziplist

2,當元素超過512個,或元素超過64字節,內部編碼變成linkedlist鏈表;

   rpush list a1 a2 ....a513  或rpush list xxxxxxxxxxxxxx

   object encoding list  //linkedlist

 

集合<SET> 用戶標籤,社交,查詢有共同興趣愛好的人,智能推薦

保存多元素,與列表不同的是不容許有重複元素,且集合是無序,一個集合最多可存2的32次方減1個元素,除了支持增刪改查,還支持集合交集、並集、差集;

命令:

 exists user    //檢查user鍵值是否存在

 sadd user a b c     //向user插入3個元素,返回3

 sadd user a b     //若再加入相同的元素,則重複無效,返回0

 smember user //獲取user的全部元素,返回結果無序

 srem user a   //返回1,刪除a元素

 scard user    //返回2,計算元素個數

 sismember user a //判斷元素是否在集合存在,存在返回1,不存在0

 srandmember user 2 //隨機返回2個元素,2爲元素個數

 spop user 2        //隨機返回2個元素a b,並將a b從集合中刪除

 smember user   //此時已沒有a b, 只有c

 

集合的交集:

  sadd user:1 zhangsan 24 girl

  sadd user:2 james 24 boy      //初始化兩個集合

  sinter user:1 user:2     //求兩集合交集, 此時返回24

 

  sadd user:3 wang 24 girl     //新增第三個元素

  sinter user:1 user:2 user:3    //求三個集合的交集,此時返回24

 

集合的並集(集合合併去重):

  sunion user:1 user:2 user:3   //三集合合併(並集),去重24

  sdiff user:1 user:2          //1和2差集,(zhangsan 24 girl)-(james 24 boy)=zhangsan girl

 

將交集(jj)、並集(bj)、差集(cj)的結果保存:

  sinterstore user_jj user:1 user:2     //將user:1 user:2的交集保存到user_jj

  sunionstore user_bj user:1 user:2 //將user:1 user:2的(並)合集保存user_bj

  sdiffstore user_cj user:1 user:2     //將user:1-user:2的差集保存user_cj

  smemebers user_cj       // 返回zhangsan girl

內部編碼:

      sadd user 1 2 3 4      //當元素個數少(小於512個)且都爲整數,redis使用intset減小內存的使用

      sadd user 1 2...513   //當超過512個或不爲整數(好比a b)時,編碼爲hashtable

      object encoding user //hashtables

使用場景:

  標籤,社交,查詢有共同興趣愛好的人,智能推薦

  使用方式:給用戶添加標籤:

  sadd user:1:fav basball fball pq

  sadd user:2:fav basball fball   

  ............

  或給標籤添加用戶

  sadd basball:users user:1 user:3

  sadd fball:users user:1 user:2 user:3

  ........

  計算出共同感興趣的人:

   sinter user:1:fav user2:fav

   規則

   sadd (經常使用於標籤)  spop/srandmember(隨機,好比抽獎)

   sadd+sinter (用於社交,查詢共同愛好的人,匹配)

 

有序集合: 經常使用於排行榜,如視頻網站須要對用戶上傳視頻作排行榜,或點贊數

與集合有聯繫,不能有重複的成員

與LIST SET 對比

命令

   zadd key score member [score member......]

   zadd user:zan 200 james     //james的點贊數1, 返回操做成功的條數1

   zadd user:zan 200 james 120 mike 100 lee    // 返回3

   zadd test:1 nx 100 james               //鍵test:1必須不存在,主用於添加

   zadd test:1 xx incr 200 james       //鍵test:1必須存在,主用於修改,此時爲300

   zadd test:1 xx ch incr -299 james //返回操做結果1,300-299=1

   zrange test:1 0 -1 withscores  //查看點贊(分數)與成員名

   zcard test:1     //計算成員個數, 返回1

查點贊數

   zadd test:2 nx 100 james //新增一個集合

   zscore test:2 james     //查看james的點贊數(分數),返回100

排名:

   zadd user:3 200 james 120 mike 100 lee    //先插入數據

   zrange user:3 0 -1 withscores         //查看分數與成員

lee

mike

james

100

120

200

    zrank user:3 james  //返回名次:第3名返回2,從0開始到2,共3名

    zrevrank user:3 james //返回0, 反排序,點贊數越高,排名越前

刪除成員:

    zrem user:3 jame mike //返回成功刪除2個成員,還剩lee

增長分數:

    zincrby user:3 10 lee     //成員lee的分數加10

    zadd user:3 xx incr 10 lee //和上面效果同樣

返回指定排名範圍的分數與成員

    zadd user:4 200 james 120 mike 100 lee    //先插入數據

    zrange user:4 0 -1 withscores     //返回結果以下圖

    zrevrange user:4 0 -1 withscores   //倒序,結果以下圖

返回指定分數範圍的成員

    zrangebyscore user:4 110 300 withscores    //返回120 lee ,200 James, 由低到高

    zrevrangebyscore user:4 300 110 withscores     //返回200james 120lee,由高到低

    zrangebyscore user:4 (110 +inf withscores        //110到無限大,120mike 200james

    zrevrangebyscore user:4 (110 -inf withscores    //無限小到110,返回100 lee

返回指定分數範圍的成員個數:

    zcount user:4 110 300  //返回2,由mike120和james200兩條數據

刪除指定排名內的升序元素:

    zremrangebyrank user:4 0 1 //分數升序排列,刪除第0個與第1個,只剩james

刪除指定分數範圍的成員

    zadd user:5 200 james 120 mike 100 lee    //先插入測試數據

    zremrangebyscore user:5 100 300             //刪除分數在100與300範圍的成員

    zremrangebyscore user:5 (100 +inf        //刪除分數大於100(不包括100),還剩lee

 

有序集合交集:

   格式:zinterstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

         destination:交集產生新的元素存儲鍵名稱

         numkeys:  要作交集計算的鍵個數

         key :元素鍵值

         weights:每一個被選中的鍵對應值乘weight, 默認爲1

  初始化數據:

       zadd user:7 1 james 2 mike 4 jack 5 kate      //初始化user:7數據

       zadd user:8 3 james 4 mike 4 lucy 2 lee  6 jim  //初始化user:8數據

  交集例子:

      zinterstore user_jj 2 user:7 user:8 aggregate sum

        //2表明鍵合併個數,aggregate sum可加也不可加上,由於默認是sum結果user_jj:4james(1+3), 6mike(2+4)

      zinterstore user_jjmax 2 user:7 user:8 aggregate max 或min

        //取交集最大的分數,返回結果 3james  4mike, min取最小

  weights:

      zinterstore user_jjweight 2 user:7 user:8 weights 8 4 aggregate max

      //1,取兩個成員相同的交集,user:7->1 james  2 mike;  user:8->3 james  4 mike

      //2,將user:7->james 1*8=8,  user:7->mike 2*8 =16, 最後user:7結果 8 james  16 mike;

      //3,將user:8-> james 3*4=12, user:8->mike 4*4=16 最後user:8結果12 james  16 mike

      //4,最終相乘後的結果,取最大值爲  12 james 16mike

      //5, zrange user_jjweight 0 -1 withscores 查詢結果爲  12 james 16mike

    總結:將user:7成員值乘8,將user:8成員值乘4,取交集,取最大

 

有序集合並集(合併去重):

格式:zunionstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

         destination:交集產生新的元素存儲鍵名稱

         numkeys:  要作交集計算的鍵個數

         key :元素鍵值

         weights:每一個被選中的鍵對應值乘weight, 默認爲1

zunionstore user_jjweight2 2 user:7 user:8 weights 8 4 aggregate max

//與以上zinterstore同樣,只是取並集,指令同樣

有序集合內部編碼

  1. ziplist:  zadd user:9 20 james 30 mike 40 lee

                    object encoding user:init

                    //當元素個數少(小於128個),元素值小於64字節時,使用ziplist編碼,可有效減小內存的使用

    2,skiplist:  zadd user:10 20 james......

                    //大於128個元素或元素值大於64字節時爲skiplist編碼

使用場景

   排行榜系統,如視頻網站須要對用戶上傳的視頻作排行榜

   點贊數:zadd user:1:20180106 3 mike  //mike得到3個贊

   再獲一讚:zincrby user:1:20180106 1 mike  //在3的基礎上加1

   用戶做弊,將用戶從排行榜刪掉:zrem user:1:20180106 mike

   展現贊數最多的5個用戶:zrevrangebyrank user:1:20180106  0  4

   查看用戶贊數與排名: zscore user:1:20180106 mike   zrank user:1:20180106 mike

PS:如何將Mysql表數據導入redis?

相關文章
相關標籤/搜索