<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # Lazyfree 大key刪除的問題想必很多用戶都遇到過,Redis除string外還支持list、set、hash和sorted set等復雜數據結構,這些數據結構豐富了Redis的用法,但是如果使用不當造成單key體積過大的話就會引起一些問題。 舉個簡單的例子,假如某社交網站有一個大V,有上百萬的粉絲,我們可以用set集合類型的數據結構來存儲他的粉絲ID,存儲粉絲集合的key叫做funs好了,我們來看下粉絲數: ~~~ 127.0.0.1:6379> SCARD funs (integer) 6320505 ~~~ 的確是大V,有600多萬的粉絲,但是很不幸的有一天這個大V注銷了,這時就要刪除他的信息,我們用DEL命令來刪除這個key: ~~~ 127.0.0.1:6379> DEL funs (integer) 1 (3.11s) 127.0.0.1:6379> slowlog get 1) 1) (integer) 4 2) (integer) 1528169923 3) (integer) 3104812 4) 1) "DEL" 2) "funs" 5) "127.0.0.1:48398" 6) "" ~~~ * 小插曲:Redis 4.0擴展了slowlog的返回結果,展示了產生慢日志的客戶端IP:PORT以便追本溯源。 可以看到刪除這個動作居然耗時3秒多,也就意味著這3秒內Redis無法執行其他命令,這對于線上業務來講是有傷害的,那么如何避免刪除大key時的阻塞問題呢?Redis 4.0推出了Lazyfree這一功能,使用UNLINK命令來刪除大key,主線程只負責把key從數據庫中"摘除",真正的釋放動作放在了BIO后臺線程去做,我們來看下效果: ~~~ 127.0.0.1:6379> UNLINK funs (integer) 1 (3.11s) 127.0.0.1:6379> slowlog get (empty list or set) ~~~ 可以看到UNLINK執行很快沒有產生slowlog。 Lazyfree一共有3個命令: 1. UNLINK:異步刪除key 2. FLUSHDB ASYNC:異步清空當前DB 3. FLUSHALL ASYNC:異步清空所有DB 以及4個配置項: 1. lazyfree-lazy-expire:異步刪除過期key 2. lazyfree-lazy-eviction:異步淘汰key 3. lazyfree-lazy-server-del:隱式刪除時采取異步刪除,比如rename a b,若b存在則需刪除b 4. slave-lazy-flush:全量同步時,slave異步清空所有DB 對于源碼實現有興趣的讀者可以閱讀 https://yq.aliyun.com/articles/205504?spm=a2c4e.11153940.blogcont600648.12.36ab1b52lTEvxh # Lua腳本支持隨機操作 Redis內嵌了Lua環境來支持用戶擴展功能,但是出于數據一致性考慮,要求腳本必須是純函數的形式,也就是說對于一段Lua腳本給定相同的參數,重復執行其結果都是相同的。 為什么要有這個限制呢?原因是Redis不僅僅是單機版的內存數據庫,它還支持主從復制和持久化,執行過的Lua腳本會復制給slave以及持久化到磁盤,如果重復執行得到結果不同,那么就會出現內存、磁盤、slave之間的數據不一致,在failover或者重啟之后造成數據錯亂影響業務。 還是以具體例子來看,假設有這么一段Lua腳本,目的很簡單就是想記錄下當前時間: ~~~ local now = redis.call('time')[1] redis.call('set','now',now) return redis.call('get','now') ~~~ 這里使用了Redis的TIME命令來獲取時間戳,然后存儲到名為now的key中,但是其執行時會報錯: ~~~ $redis-cli --eval escript (error) ERR Error running script (call to f_cfba5ec6a699dad183456f19d1099d8dabfdb80c): @user_script:3: @user_script: 3: Write commands not allowed after non deterministic commands. Call redis.replicate_commands() at the start of your script in order to switch to single commands replication mode. ~~~ 錯誤提示也很明顯,如果執行過非確定性命令(也就是TIME,因為時間是隨機的),Redis就不允許執行寫命令,以此來保證數據一致性。那如何才能實現隨機寫入呢?剛才的錯誤提示也給出了答案,使用redis.replicate_commands(),在執行redis.replicate_commands()之后,Redis就不再是把整個Lua腳本同步給slave和持久化,而是把腳本中調用Redis的寫命令直接去做復制,那么slave和持久化也可以得到確定的結果。 腳本修改如下: ~~~ redis.replicate_commands() local now = redis.call('time')[1] redis.call('set','now',now) return redis.call('get','now') ~~~ 再執行就可以實現隨機寫入了: ~~~ $redis-cli --eval escript "1528191578" $redis-cli --eval escript "1528191804" ~~~ # 基于LFU的熱點key發現機制 LFU是Redis 4.0新增的一類內存逐出策略,提供了更精確的內存淘汰算法,其本質是記錄了一段時間內key的訪問頻率,同時也帶來了額外的福利就是熱點key的發現。 LFU簡單來講就是用0-255來表示key的訪問頻率,值越大說明訪問頻率越高,并且這里對頻率的計數采用的是基于對數的概率增長,LFU為255可以代表100W次的訪問,關于LFU的實現有興趣的讀者可以參考 https://yq.aliyun.com/articles/278922?spm=a2c4e.11153940.blogcont600648.13.36ab1b52lTEvxh 使用OBJECT FREQ命令即可獲取指定key的訪問頻率,不過需要首先把內存逐出策略設置為allkeys-lfu或者volatile-lfu: ~~~ 127.0.0.1:6379> config get maxmemory-policy 1) "maxmemory-policy" 2) "noeviction" 127.0.0.1:6379> object freq counter:000000006889 (error) ERR An LFU maxmemory policy is not selected, access frequency not tracked. Please note that when switching between policies at runtime LRU and LFU data will take some time to adjust. 127.0.0.1:6379> config set maxmemory-policy allkeys-lfu OK 127.0.0.1:6379> object freq counter:000000006889 (integer) 3 ~~~ 使用scan命令遍歷所有key,再通過OBJECT FREQ獲取訪問頻率并排序,即可得到熱點key。為了方便用戶使用,Redis自帶的客戶端redis-cli也提供了熱點key發現功能,執行redis-cli時加上--hotkeys選項即可,示例如下: ~~~ $./redis-cli --hotkeys # Scanning the entire keyspace to find hot keys as well as # average sizes per key type. You can use -i 0.1 to sleep 0.1 sec # per 100 SCAN commands (not usually needed). [00.00%] Hot key 'counter:000000000002' found so far with counter 87 [00.00%] Hot key 'key:000000000001' found so far with counter 254 [00.00%] Hot key 'mylist' found so far with counter 107 [00.00%] Hot key 'key:000000000000' found so far with counter 254 [45.45%] Hot key 'counter:000000000001' found so far with counter 87 [45.45%] Hot key 'key:000000000002' found so far with counter 254 [45.45%] Hot key 'myset' found so far with counter 64 [45.45%] Hot key 'counter:000000000000' found so far with counter 93 -------- summary ------- Sampled 22 keys in the keyspace! hot key found with counter: 254 keyname: key:000000000001 hot key found with counter: 254 keyname: key:000000000000 hot key found with counter: 254 keyname: key:000000000002 hot key found with counter: 107 keyname: mylist hot key found with counter: 93 keyname: counter:000000000000 hot key found with counter: 87 keyname: counter:000000000002 hot key found with counter: 87 keyname: counter:000000000001 hot key found with counter: 64 keyname: myset ~~~ # MEMORY內存分析命令 分析內存可以優化Redis的使用方式,全新的MEMORY命令可以幫助用戶來實現這一操作。 MEMORY命令一共有5個子命令,可以通過MEMORY HELP來查看: ~~~ 127.0.0.1:6379> memory help 1) "MEMORY DOCTOR - Outputs memory problems report" 2) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key" 3) "MEMORY STATS - Show memory usage details" 4) "MEMORY PURGE - Ask the allocator to release memory" 5) "MEMORY MALLOC-STATS - Show allocator internal stats" ~~~ 關于各個子命令的詳細使用方式可以參考 https://yq.aliyun.com/articles/278910?spm=a2c4e.11153940.blogcont600648.14.36ab1b52lTEvxh
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看