Daniel-Handsome
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    **** 快得原理 https://learn.lianglianglee.com/%e4%b8%93%e6%a0%8f/Redis%20%e6%a0%b8%e5%bf%83%e6%8a%80%e6%9c%af%e4%b8%8e%e5%ae%9e%e6%88%98/03%20%20%e9%ab%98%e6%80%a7%e8%83%bdIO%e6%a8%a1%e5%9e%8b%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e5%8d%95%e7%ba%bf%e7%a8%8bRedis%e8%83%bd%e9%82%a3%e4%b9%88%e5%bf%ab%ef%bc%9f.md https://mp.weixin.qq.com/s?__biz=MzI0MDQ4MTM5NQ==&mid=2247537510&idx=2&sn=d33f3c4ed393ee49a9103f75f0ced0fc&chksm=e918367ade6fbf6cf439b29a8afd7521e17da4712ced1a0c4104f87d1792c3094214c59ffbc8&scene=21#wechat_redirect # Redis https://www.youtube.com/watch?v=G1rOthIU-uo 還未看 https://learnku.com/articles/57510 要用cli 記得進去redis後要輸入 redis-cli windos簡單安裝介紹 https://www.youtube.com/watch?v=DYv5_illdFY&list=PLBjZhzRvV2CiObno8yYFo476dcODKM3-v&index=2 apt裝 wsl service啟動 再跑start ping他 面試考題 基本 https://www.quanxiaoha.com/java-interview/redis-data-type.html ## redis pubsub原理 https://jameshfisher.com/2017/03/01/redis-pubsub-under-the-hood/ Redis Pub/Sub: 適合低延遲、實時通訊,但消息一旦發佈,不在連線狀態的訂閱者將無法補獲消息。 其保證屬於「至多一次」(at most once),並非「至少一次」 ## redis 6.0多線程 https://blog.csdn.net/chenssy/article/details/142110498 ## 快跟db差異 為什麼 Redis 的非阻塞 I/O 更優? 單線程設計:Redis 通過單線程來處理所有請求,這避免了多線程系統中常見的線程切換和鎖競爭問題。即使在處理 I/O 操作時,它也能保持較低的延遲。 內存存儲:Redis 是基於內存的資料庫,因此它的 I/O 操作主要是內存讀寫,這比磁碟 I/O 要快得多。即使是非阻塞的磁碟 I/O 操作,也不如內存操作那麼快速。 事件驅動和 I/O 多路復用:Redis 使用事件驅動和 I/O 多路復用技術來高效處理大量並發請求,這使得 Redis 能夠在單一線程中處理大量的 I/O 請求,而不需要為每個請求啟動新的線程。 ![image](https://hackmd.io/_uploads/ryux8akp1l.png) ![image](https://hackmd.io/_uploads/HJOXIak6ke.png) ![image](https://hackmd.io/_uploads/H1E48aJTye.png) ![image](https://hackmd.io/_uploads/HkcZw616Jx.png) ## pubsub ![image](https://hackmd.io/_uploads/Bk-RIja7ke.png) 都是零拷貝io ## 過期隊列 https://javaguide.cn/database/redis/redis-delayed-task.html#redis-%E8%BF%87%E6%9C%9F%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC%E5%AE%9E%E7%8E%B0%E5%BB%B6%E6%97%B6%E4%BB%BB%E5%8A%A1%E5%8A%9F%E8%83%BD%E7%9A%84%E5%8E%9F%E7%90%86 ## 復原 ![image](https://hackmd.io/_uploads/SJFlW92Fyl.png) ## golang lock https://github.com/go-redsync/redsync ## 大概說一下命令執行 https://my.oschina.net/u/3715845/blog/5062140 ## 一致 使用Binlog实时更新/删除Redis缓存。利用Canal,即将负责更新缓存的服务伪装成一个MySQL的从节点,从MySQL接收Binlog,解析Binlog之后,得到实时的数据变更信息,然后根据变更信息去更新/删除Redis缓存 ## redis資料結構應用 ![image](https://hackmd.io/_uploads/HyS18q8ap.png) ![image](https://hackmd.io/_uploads/HJrgUcUaa.png) ![image](https://hackmd.io/_uploads/rJjhUc8Tp.png) ## 基本介紹 redis跟一般資料庫不一樣 他不是存在硬體,他是存在內存(Ram),所以他非常快,但缺點是不穩定,如果電腦突然崩潰,資料會全部不見,除非你有備份他, set key value get key 支援多樣數據庫 ![](https://i.imgur.com/1s55adE.png) 如果我資料庫包含關係 可以用graph的 json的可以用 firestore mongo ![](https://i.imgur.com/iCJS9pG.png) 然後再使用搜尋的去找 ![](https://i.imgur.com/s2SzAN7.png) redis数据库一般会将存入的数据先存在 内存中,当存储的内容达到一定数量或者经过一定时间后,才将内容存 储到磁盘上,所以redis数据库对数据的存储和操作非常快,因为大部分 数据操作是在内存中完成的。同时,redis数据库要比MemCache功能更 强,因为它可以实现数据的持久化存储 Laravel框架是通过添加“predis/predis”资源包来实现与redis数据库的交 互,该资源包目前只支持前六种数据结构 ## 擴張 memcached 官方没有提供集群特性,一般第三方会使用一致性哈希算法来进行负载均衡实现集群扩展。 redis 官方的集群选择把数据根据key来哈希分配到固定数量的 slot 上,然后把 slot 再分配到具体的redis实例上来实现集群,当需要扩展时,只需要把 slot 分配一些到新加入的 redis 实例即可。这种多加一层来实现集群扩展的方式,类似于我们数据库分表时使用的索引表 ## 注意要点 https://mp.weixin.qq.com/s?__biz=MzkyMzU5Mzk1NQ==&mid=2247506058&idx=1&sn=b5d0f0eb59c348b86c38f69b8308a512&source=41#wechat_redirect ## On-demand Look-aside Cache https://tachunwu.github.io/posts/gravity-router/ ## 基本操作 redis有0~15數據庫, 默認訪問0號 ![](https://i.imgur.com/7rZzxRs.png) ## string ![](https://hackmd.io/_uploads/SJCGbK75h.png) ![image](https://hackmd.io/_uploads/SymH574h0.png) ![image](https://hackmd.io/_uploads/S1kI9X42C.png) https://segmentfault.com/a/1190000040177140 ## hash table key - field - value ## list(有序可以重複) ![](https://i.imgur.com/2BUNZGJ.png) 從頭推入 ex 1, 2, 3, 4, 5 這樣就是1先放2 . 3 . 4這樣 ## set(無序不能重複) ![](https://i.imgur.com/QRhOYLI.png) ![](https://i.imgur.com/wKzMbNK.png) ## 有續集合 zset ![](https://i.imgur.com/lFZsZlx.png) ![](https://i.imgur.com/1wNebZe.png) ## laravel lock https://learnku.com/articles/4211/unlock-the-correct-position-of-the-redis-lock ## redis 缓存和 mysql 数据一致性 ``` 方式: 1. 先更新redis 再更新数据库 场景:update set value = 10 where value = 9 1. redis更新成功:redis value = 10 2. 数据库更新失败:mysql value = 9 3. 数据不一致 2. 先更新数据库,再更新redis 场景: A进程update set value = 10 where value = 9 ;B进程 update set value = 11 where value = 9; 1. A 进程先更新数据库,还未写入缓存:mysql value = 10 ;redis value = 9 2. B 进程更新数据库并且提交事务,写入缓存:mysql value = 11;redis value = 11; 3. A 进程处理完请求提交事务,写入缓存:redis value = 10; 4. 最终 mysql value = 11; redis value = 10 3. 先删除缓存再更新数据库 场景:A进程update set value = 10 where value = 9 ;B进程查询value; 1. A 进程先删除缓存 还没来得及修改数据或者事务未提交 2. B 进程开始查询,没有命中缓存,所以查库并写入缓存 redis value = 9 3. A 进程更新数据库完成 mysql value = 10 4. 最终 mysql value = 10;redis value = 9 解决方案: 1. 延时双删除 场景:A进程update set value = 10 where value = 9 ;B进程查询value; 1. A 进程先删除缓存 还没来得及修改数据或者事务未提交 2. B 进程开始查询,没有命中缓存,所以查库并写入缓存 redis value = 9 3. A 进程更新数据库完成 mysql value = 10 4. A 进程估算延时时间,sleep之后再次删除缓存 5. 最终mysql value = 10;redis value 为空(下次查询直接查库) 6. 延时的原因时防止B进程在A进程更新完之后B进程还没来得及写入缓存 2. 请求串行化 1. 创建两个队列 :更新队列和查询队列 2. 当缓存不存在需要查库的时候将key存入更新队列 3. 如果查询未完成之前有新的请求进来,并且发现更新队列中还存在key则将key放入查询队列,则等待;不存在则重复第二步 4. 如果查询的数据发现查询队列已经存在则不需要再次写入队列 4. 数据更新完成之后rpop更新队列,同时rpop查询队列,释放查询请求 5. 查询请求可以使用while + sleep 查询缓存并且设置最大延迟时间,还没有完成则返回空 ``` ## redis 的数据类型及应用场景 ``` 1. string : 普通的key/value存储 2. hash: hashmap:键值队集合,存储对象信息 3. list: 双向链表:消息队列 4. set: value永远为null的hashMap:无序集合且不重复:计算交集、并集、差集、去重值 5. zset: 有序集合且不重复:hashMap(去重) + skiplist跳跃表(保证有序):排行榜 ``` ### zset ![](https://hackmd.io/_uploads/SkuubnQq2.png) ## redis 更新 ![](https://hackmd.io/_uploads/Syw9HK-kp.png) ![](https://hackmd.io/_uploads/S1vIx075h.png) 內存淘汰 https://xiaolincoding.com/redis/module/strategy.html#%E5%86%85%E5%AD%98%E6%B7%98%E6%B1%B0%E7%AD%96%E7%95%A5 ### cache aside pattern ![](https://hackmd.io/_uploads/r1Ik6aQ5h.png) ![](https://hackmd.io/_uploads/BywUS4Zkp.png) ![](https://hackmd.io/_uploads/r1e7Auw92.png) ## 最佳化 redis應該跟資料庫區別,因該要有redis跟資料庫,這樣當你資料有在redis裡面就能快速撈取,沒有再從資料庫拉,這樣是最佳化 ## 发布、订阅消息 。redis是通过`publish`和`subscribe subscribe`指令提供消息的发布和订阅的,通过 订阅一个“队列”用于监听消息,当有消息通过pubish指令发布到 “队 列”中时,订阅程序就会监听到消息并进行响应。为了实现上述功能, 可以使用artisan命令 ``` “php artisan make:console SubscribeMsg -- command=Sub:Msg” ``` 来创建一个订阅消息类,并修改该类的handle()函 数,通过Redis::`subscribe subscribe`()方式订阅一个“队列”,这里定义的队列名称 为“redis-msg”。但是,只创建一个控制台指令类还是不行的,需要将该 类在控制台核心类(App\Console\ Kernel)的“$commands”属性中进行注册 才能生效 ### list ![](https://hackmd.io/_uploads/ryTPNtZJp.png) ### pubusb ![](https://hackmd.io/_uploads/S1c6dKWyT.png) ![](https://hackmd.io/_uploads/ryK7KFWk6.png) ## stream 單消費者 ![](https://hackmd.io/_uploads/BynmqYWkT.png) ![](https://hackmd.io/_uploads/r1eYqt-1p.png) ![](https://hackmd.io/_uploads/B198nKZJT.png) ![](https://hackmd.io/_uploads/ByOY2tbka.png) 多消費者 ![](https://hackmd.io/_uploads/SkyEptWkp.png) ![](https://hackmd.io/_uploads/HyULCtZ1T.png) ![](https://hackmd.io/_uploads/HJTP0Y-1p.png) ![](https://hackmd.io/_uploads/rkXWs5-yp.png) ![](https://hackmd.io/_uploads/HJmqi9-ya.png) 如果生產者發送問題 或者 消息有順序 那就需要更強大的queue https://www.bilibili.com/video/BV1cr4y1671t?p=77&spm_id_from=pageDriver&vd_source=f726dd30598fe01d9fbc9c5a988d6408 ## 緩存更新 ![](https://hackmd.io/_uploads/B1ozHKbkp.png) 內存做法 可以用最新的 https://xiaolincoding.com/redis/module/strategy.html ## 操作 ### 基本 crud `set name value` `get name value` `DEL name` `exists name` 判斷有沒有 找全部的key `keys *` 刪除全部的 `flushall` ![](https://i.imgur.com/BzPMu00.png) ### 生存時間 `ttl 加上name名稱` -1代表沒有期限 -2 代表消失了 `expire naem 時間` ### list 可以看成array lpush 推一個到左邊 right 推一個ㄘㄨ從右邊 放 lpush friends john 拿 lrange friends 0 -1 這代表抓全部 刪除呢 一樣用 lpop rpop ![](https://i.imgur.com/1bG7Zip.png) ### set ![image](https://hackmd.io/_uploads/rk_JOiVR1e.png) ![image](https://hackmd.io/_uploads/ByfgOiVAke.png) 可以當成js的那個 有唯一值的 SADD name value 查看全部 smembers 刪除 srem ![](https://i.imgur.com/6SdiaiL.png) ### hashes 你不能往它裡面放嵌套 你可以把她想成json Hset Hget HgetAll 看全部 刪除 hdel 他其實是兩層的 ![](https://i.imgur.com/8HMMdG1.png) ## 指令 setex 如果有 覆蓋舊的 ## pipeline ![](https://i.imgur.com/IHsgUNJ.png) before ![](https://i.imgur.com/YxNoZqX.png) after ![](https://i.imgur.com/sTHYZCk.png) 有前後關西不能用 後面需要前面不能用 跟一般的管道不太一樣 ## 事務 ![](https://i.imgur.com/fyoyIOn.png) ## watch ![](https://i.imgur.com/nZmpVie.png) ## LFU ## Redis server-assisted client side caching https://www.51cto.com/article/707706.html https://www.51cto.com/article/617014.html Guava Cache等本地緩存 ## refresh時機 主動被動 主動會去找更新 被動 在觸發CDC (Change Data Capture) 後去改動 ## 事務 https://www.cnblogs.com/makemylife/p/17299566.html 記住事物不會rollback ###### tags: `資料庫相關`

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully