Redis系列:Redis的概述與安裝

Redis(Remote Dictionary Server) 是一個使用 C 語言編寫的,開源的(BSD許可)高性能非關系型(NoSQL)的鍵值對數據庫。

本篇內容包括:Redis 簡介(為什么快?為什么單線程?優點,缺點等),Redis 在 Java Web 中的應用,Redis 安裝(Win、Linux、Mac 場景下的安裝)等內容


文章目錄

    • 一、Redis 簡介
        • 1、Redis為什么快呢?
        • 2、Redis為何選擇單線程?
        • 3、那為什么Redis6.0之后又改用多線程呢?
        • 4、Redis的優勢
        • 5、Redis的缺點
    • 二、Redis 在 Java Web 中的應用
        • 1、Redis 的使用場景
        • 2、緩存
        • 3、高速讀/寫的場合
    • 三、Redis 安裝
        • 1、Windows 下安裝
        • 2、Linux 下安裝
        • 3、Mac 下安裝(使用Homebrew)


一、Redis 簡介

Redis 是 C 語言開發的一個開源的(遵從 BSD 協議)高性能鍵值對(key-value)的內存數據庫,可以用作數據庫、緩存、消息中間件等。

它是一種 NoSQL(not-only sql,泛指非關系型數據庫)的數據庫。是一種基于內存的數據庫,并且提供一定的持久化功能。

Redis 作為一個內存數據庫:性能優秀,數據在內存中,讀寫速度非常快,支持并發 10W QPS。單進程單線程,是線程安全的,采用 IO 多路復用機制。豐富的數據類型,支持字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。支持數據持久化。可以將內存中數據保存在磁盤中,重啟時加載。主從復制,哨兵,高可用。可以用作分布式鎖。可以作為消息中間件使用,支持發布訂閱。

1、Redis為什么快呢?

redis的速度非常的快,單機的redis就可以支撐每秒10幾萬的并發,相對于mysql來說,性能是mysql的幾十倍。速度快的原因主要有幾點:

  1. 完全基于內存操作
  2. C語言實現,優化過的數據結構,基于幾種基礎的數據結構,redis做了大量的優化,性能極高
  3. 使用單線程,無上下文的切換成本
  4. 基于非阻塞的IO多路復用機制

2、Redis為何選擇單線程?

  • 避免過多的上下文切換開銷。程序始終運行在進程中單個線程內,沒有多線程切換的場景。
  • 避免同步機制的開銷:如果 Redis選擇多線程模型,需要考慮數據同步的問題,則必然會引入某些同步機制,會導致在操作數據過程中帶來更多的開銷,增加程序復雜度的同時還會降低性能。
  • 實現簡單,方便維護:如果 Redis使用多線程模式,那么所有的底層數據結構的設計都必須考慮線程安全問題,那么 Redis 的實現將會變得更加復雜。

3、那為什么Redis6.0之后又改用多線程呢?

Redis 使用多線程并非是完全摒棄單線程,Redis 還是使用單線程模型來處理客戶端的請求,只是使用多線程來處理數據的讀寫和協議解析,執行命令還是使用單線程。

這樣做的目的是因為redis的性能瓶頸在于網絡 IO 而非 CPU,使用多線程能提升 IO 讀寫的效率,從而整體提高 Redis 的性能。

4、Redis的優勢

  • Redis支持保存多種數據結構(支持string,list,set,sorted set,hash),其單個value的最大限制是1GB,因此Redis可以用來實現很多有用的功能;
  • 因為是純內存操作,Redis的性能非常出色,每秒可以處理超過 10萬次讀寫操作,是已知性能最快的Key-Value DB;
  • Redis也可以對存入的Key-Value設置expire時間,因此也可以被當作一 個功能加強版的memcached來用;
  • Redis可以將內存的數據利用快照和日志的形式保存到硬盤上,這樣在發生類似斷電或者機器故障的時 候,內存中的數據不會“丟失”;
  • 除了上述功能以外,Redis還提供了鍵過期、發布訂閱、事務、流水線、Lua腳本等附加功能。

5、Redis的缺點

Redis的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要局限在較小數據量的高性能操作和運算上。

總之,如果在合適的場景使用好Redis,它就會像一把瑞士軍刀一樣所向披靡、無往不利!!!


二、Redis 在 Java Web 中的應用

1、Redis 的使用場景

Redis 根據使用數據類型的不同,對應的使用場景有很多,例如:

  1. 緩存(String / Hash 類型):緩存如用戶信息,視頻信息等;
  2. 分布式鎖(String 類型):setnx 方法,「key不存在才插入」,可以用它來實現分布式鎖;
  3. 計數器(String 類型):incr/decr 方法,自增自減,由于是原子性,可以用來計數統計瀏覽數、點贊數等;
  4. 限制請求次數(String 類型):也是利用 incr 方法,限制請求次數訪問者的 ip 和其他信息作為 key,訪問一次增加一次計數,超過次數則返回 false;
  5. 數據共享分布式(String 類型):因為 Redis 是分布式的獨立服務,可以在多個應用之間共享,所有可以實現需要例如分布式 Session;
  6. 購物車(Hash 類型):類似存儲商品信息,大 key 為商家 id,小 key 是商品 id 即 goodsId,value 為該 goodsId 的詳細信息;
  7. 消息隊列(List / Stream 類型):二者都可以實現消息隊列,而 Redis5.0 新增的 Stream,解決了 List 實現的消息隊列不能持久化和不能重復消費的問題;
  8. 點贊、踩、收藏(Set 類型):Set 集合無需、不可重復,可以保證一個用戶只能點一個贊;
  9. 共同關注(Set 類型):Set 類型支持交集運算,所以可以用來計算共同關注的好友、公眾號等;
  10. 抽獎活動(Set 類型):存儲某活動中中獎的用戶名 ,Set 類型因為有去重功能,可以保證同一個用戶不會中獎兩次;
  11. 排行榜(ZSet 類型):有序集合保留了集合不能有重復成員的特性(分值可以重復),但不同的是,有序集合中的元素可以排序,所以可以用作排行榜功能的實現;
  12. 此外利用 Redis 的特殊數據類型也可以實現一些相應的功能:Bit 位運算用來簽到統計、HyperLogLogs 統計基數用來百萬級網絡 UV,還有 GEO 地理位置、用來打車等;

2、緩存

在日常對數據庫的訪問中,讀操作的次數遠超寫操作,比例大概在 1:93:7,所以需要讀的可能性是比寫的可能大得多的。當我們使用SQL語句去數據庫進行讀寫操作時,數據庫就會去磁盤把對應的數據索引取回來,這是一個相對較慢的過程。

如果我們把數據放在 Redis 中,既直接放在內存之中,讓服務端直接去讀取內存中的數據,那么這樣速度明顯就會快上不少,并且會極大減小數據庫的壓力,但是使用內存進行數據存儲開銷也是比較大的,限于成本的原因,一般我們只是使用 Redis 存儲一些常用和主要的數據,比如用戶登錄的信息等。

一般而言在使用 Redis 進行存儲的時候,我們需要從以下幾個方面來考慮:

  • 業務數據常用嗎?命中率如何?如果命中率很低,就沒有必要寫入緩存;
  • 該業務數據是讀操作多,還是寫操作多?如果寫操作多,頻繁需要寫入數據庫,也沒有必要使用緩存;
  • 業務數據大小如何?如果要存儲幾百兆字節的文件,會給緩存帶來很大的壓力,這樣也沒有必要。

在考慮了這些問題之后,如果覺得有必要使用緩存,那么就使用它!

使用 Redis 作為緩存的讀取邏輯如下圖所示:

Redis緩存讀取邏輯

從上圖我們可以知道以下兩點:

  1. 當第一次讀取數據的時候,讀取 Redis 的數據就會失敗,此時就會觸發程序讀取數據庫,把數據讀取出來,并且寫入 Redis 中;
  2. 當第二次以及以后需要讀取數據時,就會直接讀取 Redis,讀到數據后就結束了流程,這樣速度就大大提高了。

從上面的分析可以知道,讀操作的可能性是遠大于寫操作的,所以使用 Redis 來處理日常中需要經常讀取的數據,速度提升是顯而易見的,同時也降低了對數據庫的依賴,使得數據庫的壓力大大減少。

使用 Redis 作為緩存的寫入邏輯如下圖所示:

Redis緩存寫入邏輯.png

從流程可以看出,更新或者寫入的操作,需要多個 Redis 的操作,如果業務數據寫次數遠大于讀次數那么就沒有必要使用 Redis。

3、高速讀/寫的場合

在如今的互聯網中,越來越多的存在高并發的情況,比如天貓雙11、搶紅包、搶演唱會門票等,這些場合都是在某一個瞬間或者是某一個短暫的時刻有成千上萬的請求到達服務器,如果單純的使用數據庫來進行處理,就算不崩,也會很慢的,輕則造成用戶體驗極差用戶量流失,重則數據庫癱瘓,服務宕機,而這樣的場合都是不允許的!

所以我們需要使用 Redis 來應對這樣的高并發需求的場合,我們先來看看一次請求操作的流程圖:

Redis高速讀寫的場合

我們來進一步闡述這個過程:

  1. 當一個請求到達服務器時,只是把業務數據在 Redis 上進行讀寫,而沒有對數據庫進行任何的操作,這樣就能大大提高讀寫的速度,從而滿足高速響應的需求;
  2. 但是這些緩存的數據仍然需要持久化,也就是存入數據庫之中,所以在一個請求操作完 Redis 的讀/寫之后,會去判斷該高速讀/寫的業務是否結束,這個判斷通常會在秒殺商品為0,紅包金額為 0 時成立,如果不成立,則不會操作數據庫;如果成立,則觸發事件將 Redis 的緩存的數據以批量的形式一次性寫入數據庫,從而完成持久化的工作。

三、Redis 安裝

1、Windows 下安裝

  1. 官方沒有 Windows版本的 Redis

  2. Windows版本下載地址:https://github.com/MicrosoftArchive/redis/releases,下載 Redis-x64-3.2.100.msi

  3. 雙擊剛下載好的msi格式的安裝包(Redis-x64-3.2.100.msi):

    1. 開始安裝

    2. 選擇“同意協議”,點擊下一步繼續:

    3. 選擇“添加Redis目錄到環境變量PATH中”,這樣方便系統自動識別Redis執行文件在哪里:

    4. 端口號可保持默認的6379,并選擇防火墻例外,從而保證外部可以正常訪問Redis服務:

    5. 設定最大值為100M。作為實驗和學習,100M足夠了:

  4. 右擊“計算機”>選擇“管理”。在左側欄中依次找到并點擊“計算機管理(本地)”> 服務和應用程序 > 服務。再在右側找到Redis名稱的服務,查看啟動情況。如未啟動,則手動啟動之。正常情況下,服務應該正常啟動并運行了

  5. 最后來測試一下 Redis 是否正常提供服務。進入 Redis 的目錄使用cmd。輸入redis-cli并回車。(redis-cli是客戶端程序)如圖正常提示進入,并顯示正確端口號,則表示服務已經啟動

    批注 2021-07-08 1935126

  6. 實際測試一下讀寫。輸入set mykey1 "I love you all!"并回車,用來保存一個鍵值。再輸入get mykey1,獲取剛才保存的鍵值

2、Linux 下安裝

  1. Redis官網 https://redis.io/ 直接點擊下載得到:redis-6.2.4.tar.gz

  2. 把 redis-6.2.4.tar.gz 移動到/usr/local/ 目錄下 : mv redis-6.2.4.tar.gz /usr/local/

  3. 解壓 redis-6.2.4.tar.gz : tar -zxvf redis-6.2.4.tar.gz

  4. 由于redis是由C語言編寫的,它的運行需要C環境,因此我們需要先安裝gcc : yum install gcc-c++

  5. 進入到 /usr/local/redis-6.2.4/ 目錄下,進行編譯與安裝 :cd redis-6.2.4makecd ./srcmake install

  6. Redis不是默認后臺啟動的,需要求改一下配置文件:vi redis.confdaemonize 屬性改為 yes

  7. 編輯 redis.conf配置文件,開啟redis遠程訪問服務:

    • 配置文件中的 bind 127.0.0.1 這一行給注釋掉,這里的bind指的是只有指定的網段才能遠程訪問這個redis,注釋掉后,就沒有這個限制了
    • 配置文件中的 protected-mode 設置成 no(默認是設置成yes的, 防止了遠程訪問,在redis3.2.3版本后)
  8. 啟動redis服務: redis-server redis.conf

  9. 啟動redis客戶端服務:redis-cli -p 6379

  10. 打開RedisDesktopManager,測試服務是否開啟 以及 是否可以遠程訪問Redis\

    批注 2021-07-08 204649

3、Mac 下安裝(使用Homebrew)

  1. 沒有安裝Homebrew,首先安裝npm國內的吧,快一些:/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)";
  2. 使用Homebrew安裝命令:brew install redis
  3. 查看安裝及配置文件位置:
    • Homebrew安裝的軟件會默認在/usr/local/Cellar/路徑下
    • redis的配置文件redis.conf存放在/usr/local/etc路徑下
  4. 啟動redis服務:redis-server /usr/local/etc/redis.confbrew services start redisredis-server
  5. 查看redis服務進程:ps axu | grep redis
  6. redis-cli連接redis服務,redis默認端口號6379,默認auth為空:redis-cli -h 127.0.0.1 -p 6379

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535473.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535473.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535473.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

安裝LibreOffice和字體

#/bin/bash # Check if user is root if [ $(id -u) ! "0" ]; thenecho "Error: You must be root to run this script, please use root"exit 1 fi echo 安裝LibreOffice cd /home/ tar -zxvf LibreOffice_6.3.3_Linux_x86-64_rpm.tar.gz cd /home/LibreO…

xtrabackup備份腳本

#!/bin/sh #備份主機 remote_ip100.0.132.160 Master_ip100.20.132.158 VIP100.20.132.166 #備份用戶 userroot #密碼 password00000 # 返回年月日 backup_datedate %F # 返回時分秒 backup_timedate %H-%M-%S # 返回今天是這周的第幾天 backup_week_daydate %u backup_ok0 #備…

Redis系列:使用Redis實現分布式鎖及相關問題

分布式鎖其實就是,控制分布式系統不同進程共同訪問共享資源的一種鎖的實現。如果不同的系統或同一個系統的不同主機之間共享了某個臨界資源,往往需要互斥來防止彼此干擾,以保證一致性。 本篇內容包括:關于 Redis 與 分布式鎖&…

Redis系列:Redis持久化機制與Redis事務

Redis 是個基于內存的數據庫。那服務一旦宕機,內存中數據必將全部丟失。所以丟失數據的恢復對于 Redis 是十分重要的,我們首先想到是可以從數據庫中恢復,但是在由 Redis 宕機時(說明相關工作正在運行)且數據量很大情況…

Java基礎:Java程序設計環境

按應用范圍,Java 可分為 3 個體系,即 Java SE、Java EE 和 Java ME。Java 語言的開發運行,也離不開 Java 語言的運行環境 JRE。沒有 JRE 的支持,Java 語言便無法運行。當然,如果還想編譯 Java 程序,搞搞小開…

負載均衡策略

輪循均衡(Round Robin):每一次來自網絡的請求輪流分配給內部中的服務器,從1至N然后重新開始。此種均衡算法適合于服務器組中的所有服務器都有相同的軟硬件配置并且平均服務請求相對均衡的情況。 我們的業務web服務器都是同樣配置…

Java基礎:Java數據類型

Java 是一種強類型語言,這就意味著必須為每一個變量聲明一種類型。在 Java 中基本數據類型共有 8 種,包括 4 種整型、2 種浮點型、1 種用于表現 Unicode 編碼的字符單元的字符類型 char 和一種用于表示真值的 boolean 類型 ~ 本篇主要記錄內容包括&#…

TCP連接的建立與終止

TCP連接的建立與終止 1.三次握手 TCP是面向連接的,無論哪一方向另一方發送數據之前,都必須先在雙方之間建立一條連接。在TCP/IP協議中,TCP協議提供可靠的連接服務,連接是通過三次握手進行初始化的。三次握手的目的是同步連接雙方…

日常問題:MySQL排序字段數據相同不能分頁問題

【問題日期】 2022-11-14 22:45:12 【問題描述】 MySQL 排序字段數據相同不能分頁問題:在分頁查詢數據時,按創建時間排序,由于數據是批量創建的,導致部分數據創建時間一樣,而此時分頁查詢數據,翻頁后出現…

數據缺失值處理

數據缺失值處理 In [1]: import pandas as pd import numpy as np from sklearn.ensemble import RandomForestRegressor,RandomForestClassifier from sklearn.preprocessing import StandardScaler from sklearn.impute import SimpleImputer In [2]: df pd.DataFrame() df[…

Java基礎:Java數字類型

Java 中包含多種運算符:算數運算符、關系運算符、邏輯運算符、位運算符。在 Math 類中,包含了各種各樣的數學函數。在編寫不同類別的程序時,可能需要的函數也不同。要生成一個隨機數,可以使用 Random 對象。 ~ 本篇主要…

Java基礎:Java流程控制

塊(即復合語句)是指由一對大括號括起來的若干條簡單的 Java 語句。塊確定了變量的作用域。一個塊可以嵌套在另一個塊中。但是,不能在嵌套的兩個塊中聲明同名的變量。使用塊(有時稱為復合語句)可以在Java程序結構中原本…

Java基礎:Java類與對象

面向對象程序設計(簡稱OOP)是當今主流的程序設計范型,它已經取代了20世紀70年代的“結構化”過程化程序設計開發技術。Java是完全面向對象的,必須熟悉OOP才能夠編寫Java程序。面向對象的程序是由對象組成的,每個對象包…

SVN備份腳本

#!/bin/bash #svn全量備份腳本 wwytcode_path/home/wwytcode/project backup_path/home/bak Datedate %Y%m%d cd $backup_path echo date >> $back_path/svn_backup.log svnversionsvnlook youngest $wwytcode_path svnadmin dump --revision 0:$svnversion $wwytcode_pa…

Java基礎:Java面向對象

面向過程的優點是性能比面向對象高,不需要面向對象的實例化;缺點是不容易維護、復用和擴展。面向對象的優點是具有封裝、繼承、多態的特性,因而容易維護、復用和擴展,可以設計出低耦合的系統;缺點是由于需要實例化對象…

薪資生成

import openpyxl from openpyxl.styles import Font,Alignment,Side,Border#設置字體樣式 fontFont(name宋體,size20,boldTrue) font2Font(name宋體,size12,boldTrue) alignmentAlignment(horizontalcenter,verticalcenter,wrap_textTrue) sideSide(stylethin ,color000000) …

Java基礎:Java抽象接口

在Java中,一個沒有方法體的方法應該定義為抽象方法,而如果一個類中含有抽象方法,則該類必須定義為一個抽象類。接口是功能的集合,同樣可看做是一種特殊的數據類型,是比抽象類更為抽象的類,接口只描述所應該…

13 張圖帶你學懂 Kubernetes Service(轉載)

在 Kubernetes 中 Service 主要有4種不同的類型,其中的 ClusterIP 是最基礎的,如下圖所示: 當我們創建一個 NodePort 的 Service 時,它也會創建一個 ClusterIP,而如果你創建一個 LoadBalancer,它就會創建一…

Java基礎:Java異常機制

異常是程序運行過程中出現的錯誤。Java 把異常當作對象來處理,把異常信息封裝成了一個類,并定義一個基類java.lang.Throwable作為所有異常的超類。Throwable : 它是所有錯誤與異常的超類(祖宗類),有兩個子類 Error 和 Exception。…

JavaWeb:Servlet的應用及接口介紹

廣義的 Servlet 泛指在服務器上運行的 Java 程序,但是這個 Java 程序,并不能獨立運行(因為 Servlet 沒有 main 方法),需要部署在相應的 Servlet 容器中,比如 Tomcat 和 Jetty。Servlet 主要功能在于交互式地…