標籤: 台北網頁設計公司

  • 樂視超級汽車LeSEE亮相 首推無人駕駛功能

    樂視超級汽車LeSEE亮相 首推無人駕駛功能

    4月21日,在樂視體育生態中心,樂視舉辦“無破界 不生態”為主題的春季新品發佈會。面對全球2600名媒體記者和近8000名樂迷,樂視發佈無人駕駛超級汽車。

    賈躍亭與樂視超級汽車聯合創始人、全球副董事長丁磊先生用極具創意的方式揭幕了LeSEE品牌的首款概念樣車,並演示了超級汽車的自動駕駛功能。

    LeSEE的這款概念車有著獨具“互聯網感”的外形,前臉配有超大炫酷的LED屏,可向路人顯示車輛狀態。這款概念車主打智慧互聯概念,不僅可以實現自動駕駛功能,還可實現自我學習,具備人臉識別、情緒識別、環境識別和路徑識別等功能。

    由於時間關係,當晚的汽車亮相環節只有不到五分鐘,萬眾期待的超級汽車可以用“猶抱琵琶半遮面”來形容,觀眾們都大呼“不過癮”。丁磊表示,如果想親密接觸這款凝聚了樂視汽車生態理念的智能互聯網電動車,只需在5天之後的北京車展上一睹為快。

    據丁磊透露,除了這款承載了樂視互聯電動智慧共用交通生態系統的概念車,樂視在將在近期宣佈和國內一家主流汽車集團的合作,以及在美國矽谷成立全球首家汽車主機廠與互聯網公司共同成立的人工智慧研究院——“FF& Le Future”人工智慧研究院。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

    小三通物流營運型態?

    ※快速運回,大陸空運推薦?

  • Zabbix-(四)郵件、釘釘告警通知

    Zabbix-(四)郵件、釘釘告警通知

    Zabbix-(四)郵件、釘釘告警通知

    一.前言

    在之前的文章里,通過Zabbix對主機的磁盤、CPU以及內存進行了監控,並在首頁Dashboard里創建了監控圖形,但是只有當我們登錄到Zabbix后才能看到監控到的問題(Problem),因此在本篇文章里,將利用觸發器(Trigger),以及媒介(Media)等配置項,實現當觸發器觸發時,通過不同媒介,如:郵件、釘釘,發送動作(Action),實現實時通知告警功能。

    準備

    • Zabbix Server (Zabbix 4.4)
    • 在Zabbix中已配置一些監控項和觸發器(這些配置可以參考我的)

    二.安裝相關環境

    由於使用到腳本告警媒介,本文中通過調用Python腳本觸發告警,因此需要在Zabbix Server主機上安裝pip以及相關模塊。(這裏Python使用Centos7自帶的Python2.7.5)

    1. 安裝pip

      # yum install -y epel-release
      
      # yum install -y python-pip
    2. 安裝requests模塊

      # pip install requests

    三.配置告警媒介類型

    Zabbix默認自帶了2種報警媒介類型(Media Type)电子郵件以及短信,我們將修改电子郵件類型配置,並新建腳本類型和Webhook類型。希望通過腳本、Webhook告警媒介發送釘釘消息。

    注:Webhook告警媒介是Zabbix 4.4的新特性

    1. 修改电子郵件告警媒介

      點擊【管理】-【報警媒介類型】-【Email】

      修改Email配置,我這裏用的是Outlook郵箱,具體SMTP服務器可以參考。使用其他郵箱也可以去對應官網查詢SMTP配置。

      測試發送郵箱,點擊【測試】

      輸入收件人郵箱

      收到郵件

    2. 新增腳本告警媒介

      新建Python腳本告警媒介,用戶釘釘告警

      點擊【創建媒體類型】

      進行配置

      配置項
      * 名稱 Python腳本
      類型 腳本
      * 腳本名稱 pythonScript.py
      腳本參數(參數1) {ALERT.MESSAGE}
      腳本參數(參數2) {ALERT.SENDTO}
      腳本參數(參數3) {ALERT.SUBJECT}

      接下來新建Python腳本,Zabbix Server配置文件中可以配置告警腳本路徑,默認為 /usr/lib/zabbix/alertscripts

      # 查看告警腳本路徑
      # cat zabbix_server.conf | grep AlertScriptsPath

      編寫告警腳本

      # cd /usr/lib/zabbix/alertscripts
      # vim pythonScript.py

      腳本內容

      #!/usr/bin/env python
      #coding:utf-8
      
      import requests,json,sys,os,datetime
      
      # 釘釘機器人地址
      webhook="https://oapi.dingtalk.com/robot/send?access_token=your_dingding_robot_access_token"
      
      # 對應{ALERT.SENDTO}, Zabbix告警媒介配置界面第2個參數
      user=sys.argv[2]
      
      # 對應{ALERT.MESSAGE}, Zabbix告警媒介配置界面第1個參數
      text=sys.argv[1]
      data={
          "msgtype": "text",
          "text": {
              "content": text
          },
          "at": {
              "atMobiles": [
                  user
              ],
              "isAtAll": False
          }
      }
      headers = {'Content-Type': 'application/json'}
      x=requests.post(url=webhook,data=json.dumps(data),headers=headers)

      給腳本可執行權限

      # chmod uo+x /usr/lib/zabbix/alertscripts/pythonScript.py

      測試腳本

      釘釘收到消息

    3. 新增Webhook告警媒介

      配置項
      * 名稱 Webhook
      類型 Webhook
      參數: (名稱)
      user {ALERT.SENDTO}
      subject {ALERT.SUBJECT}
      message {ALERT.MESSAGE}

      腳本:

      try {
          Zabbix.Log(4, 'params= '+value);
      
          params = JSON.parse(value);
          req = new CurlHttpRequest();
          data = {};
          result = {};
      
          req.AddHeader('Content-Type: application/json');
      
          data.msgtype = "text";
          //   對應 message參數
          data.text = {"content" : params.message};
          //   對應 user參數
          data.at = {"atMobiles": [params.user], "isAtAll": "false"};
      
          //   釘釘機器人
          resp = req.Post('https://oapi.dingtalk.com/robot/send?access_token=your_access_token',
              JSON.stringify(data)
          );
      } catch (error) {
          result = {};
      }
      
      return JSON.stringify(result);

      測試Webhook

    四.為用戶添加告警媒介

    需要將新增的告警媒介添加給用戶

    點擊【用戶】-【告警媒介】

    將上述步驟添加的告警媒介(Python腳本、Webhoob、Email),進行添加(收件人根據告警媒介類型填寫郵箱手機號),嚴重性也根據需要勾選。

    五.配置動作

    完成上述配置完成后,需要創建動作(Action),將觸發器(Trigger)告警媒介(Media Type)進行關聯,一旦觸發器觸發,那麼Zabbix會執行動作,再去執行告警媒介。

    1. 添加動作

      點擊【配置】-【動作】-【創建動作】

    2. 配置【動作】相關信息

      配置項
      * 名稱 告警動作
      新的觸發條件 【觸發器】【等於】【Template Disk Free Size: 磁盤剩餘空間觸發器】

      操作步驟如下圖:

      群組選擇 ->Linux servers

      主機選擇 -> Template Disk Free Size 模板()

      勾選觸發器 -> 磁盤剩餘空間觸發器 ()

      勾選後點擊【選擇】

    3. 配置【操作】相關信息

      點擊【操作】

      先配置以下信息

      配置項
      * 默認操作步驟持續時間 1h(保持默認)
      默認標題 告警: {EVENT.NAME}
      消息內容 【磁盤空間不足告警】
      告警事件: {EVENT.DATE} {EVENT.TIME}
      告警問題: {EVENT.NAME}
      告警主機: {HOST.IP} {HOST.NAME}
      告警級別: {EVENT.SEVERITY}
      磁盤剩餘:{ITEM.VALUE}

      上述配置表格【默認標題】和【消息內容】值中形如{EVENT.NAME}的內容是Zabbix中的宏(Marco),宏是一個變量,例如 {HOST.IP} 表示告警主機的IP地址,Zabbix自帶的宏可以參考

      繼續配置操作

      點擊【新的】

      【操作類型】選擇發送消息,【發送到用戶】添加Admin

      【僅送到】根據需要選擇之前配置的,本文選擇Email和Python腳本(這裏只能單選或全選,所以需要先選擇一個,因此需要多次)

      添加完成後點擊【添加】

    六.測試

    向被監控主機拷貝或下載大文件,使其磁盤剩餘空間低於觸發器監控閾值,等待觸發器觸發問題,查看儀錶盤、郵件等。

    儀錶盤

    釘釘

    郵件

    七.參考文檔

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • Dev 日誌 | 一次 Segmentation Fault 和 GCC Illegal Instruction 編譯問題排查

    Dev 日誌 | 一次 Segmentation Fault 和 GCC Illegal Instruction 編譯問題排查

    摘要

    筆者最近在重新整理和編譯 Nebula Graph 的第三方依賴,選出兩個比較有意思的問題給大家分享一下。

    Flex Segmentation Fault——Segmentation fault (core dumped)

    在編譯 Flex 過程中,遇到了 Segmentation fault:

    make[2]: Entering directory '/home/dutor/flex-2.6.4/src'
    ./stage1flex   -o stage1scan.c ./scan.l
    make[2]: *** [Makefile:1696: stage1scan.c] Segmentation fault (core dumped)

    使用 gdb 查看 coredump:

    Core was generated by `./stage1flex -o stage1scan.c ./scan.l'.
    Program terminated with signal SIGSEGV, Segmentation fault.
    #0  flexinit (argc=4, argv=0x7ffd25bea718) at main.c:976
    976             action_array[0] = '\0';
    (gdb) disas
    Dump of assembler code for function flexinit:
       0x0000556c1b1ae040 <+0>:     push   %r15
       0x0000556c1b1ae042 <+2>:     lea    0x140fd(%rip),%rax        # 0x556c1b1c2146
       ...
       0x0000556c1b1ae20f <+463>:   callq  0x556c1b1af460 <allocate_array> #這裏申請了buffer
       ...
    => 0x0000556c1b1ae24f <+527>:   movb   $0x0,(%rax) # 這裏向buffer[0]寫入一個字節,地址非法,掛掉了
       ...
    (gdb) disas allocate_array
    Dump of assembler code for function allocate_array:
       0x0000556c1b1af460 <+0>:     sub    $0x8,%rsp
       0x0000556c1b1af464 <+4>:     mov    %rsi,%rdx
       0x0000556c1b1af467 <+7>:     xor    %eax,%eax
       0x0000556c1b1af469 <+9>:     movslq %edi,%rsi
       0x0000556c1b1af46c <+12>:    xor    %edi,%edi
       0x0000556c1b1af46e <+14>:    callq  0x556c1b19a100 <reallocarray@plt> # 調用庫函數申請內存
       0x0000556c1b1af473 <+19>:    test   %eax,%eax # 判斷是否為 NULL
       0x0000556c1b1af475 <+21>:    je     0x556c1b1af47e <allocate_array+30># 跳轉至NULL錯誤處理
       0x0000556c1b1af477 <+23>:    cltq   # 將 eax 符號擴展至 rax,造成截斷
       0x0000556c1b1af479 <+25>:    add    $0x8,%rsp
       0x0000556c1b1af47d <+29>:    retq
       ...
    End of assembler dump.

    可以看到,問題出在了 allocate_array 函數。因為 reallocarray 返回指針,返回值應該使用 64 bit 寄存器rax,但 allocate_array 調用 reallocarray 之後,檢查的卻是 32 bit 的 eax,同時使用 cltq 指令將 eax 符號擴展 到 rax。原因只有一個:allocate_array 看到的 reallocarray 的原型,與 reallocarry 的實際定義不符。翻看編譯日誌,確實找到了 implicit declaration of function ‘reallocarray’ 相關的警告。configure 階段添加 CFLAGS=-D_GNU_SOURCE 即可解決此問題。

    注:此問題不是必現,但編譯/鏈接選項 -pie 和 內核參數 kernel.randomize_va_space 有助於復現。

    總結:

    • 隱式聲明的函數在 C 中,返回值被認為是 int
    • 關注編譯器告警,-Wall -Wextra 要打開,開發模式下最好打開 -Werror。

    GCC Illegal Instruction——internal compiler error: Illegal instruction

    前陣子,接到用戶反饋,在編譯 Nebula Graph 過程中遭遇了編譯器非法指令的錯誤,詳見(#978)[]

    錯誤信息大概是這樣的:

    Scanning dependencies of target base_obj_gch
    [ 0%] Generating Base.h.gch
    In file included from /opt/nebula/gcc/include/c++/8.2.0/chrono:40,
    from /opt/nebula/gcc/include/c++/8.2.0/thread:38,
    from /home/zkzy/nebula/nebula/src/common/base/Base.h:15:
    /opt/nebula/gcc/include/c++/8.2.0/limits:1599:7: internal compiler error: Illegal instruction
    min() _GLIBCXX_USE_NOEXCEPT { return FLT_MIN; }
    ^~~
    0xb48c5f crash_signal
    ../.././gcc/toplev.c:325
    Please submit a full bug report,
    with preprocessed source if appropriate.

    既然是 internal compiler error,想必是 g++ 本身使用了非法指令。為了定位具體的非法指令集及其所屬模塊,我們需要復現這個問題。幸運的是,下面的代碼片段就能觸發:

    #include <thread>
    int main() 
    {
        return 0;
    }

    非法指令一定會觸發 SIGILL,又因為 g++ 只是編譯器的入口,真正幹活的是 cc1plus。我們可以使用 gdb 來運行編譯命令,抓住子進程使用非法指令的第一現場:

    $ gdb --args /opt/nebula/gcc/bin/g++ test.cpp
    gdb> set follow-fork-mode child
    gdb> run
    Starting program: /opt/nebula/gcc/bin/g++ test.cpp
    [New process 31172]
    process 31172 is executing new program: /opt/nebula/gcc/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/cc1plus
    Thread 2.1 "cc1plus" received signal SIGILL, Illegal instruction.
    [Switching to process 31172]
    0x00000000013aa0fb in __gmpn_mul_1 ()
    gdb> disas
    ...
    0x00000000013aa086 <+38>: mulx (%rsi),%r10,%r8
    ...

    Bingo!mulx 屬於 BMI2 指令集,報錯機器 CPU 不支持該指令集。
    仔細調查,引入該指令集的是 GCC 的依賴之一,GMP。默認情況下,GMP 會在 configure 階段探測當前機器的 CPU 具體類型,以期最大化利用 CPU 的擴展指令集,提升性能,但卻犧牲了二進制的可移植性。解決方法是,configure 之前,使用代碼目錄中的 configfsf.guess configfsf.sub 替換或者覆蓋默認的 config.guess 和 config.sub

    總結:

    • 某些依賴可能因為性能或者配置的原因,造成二進制的不兼容。
    • 缺省參數下,GCC 為了兼容性,不會使用較新的指令集。
    • 為了平衡兼容性和性能,你需要做一些額外的工作,比如像 glibc 那樣在運行時選擇和綁定某個具體實現。

    最後,如果你想嘗試編譯一下 Nebula 源代碼可參考以下方式:

    bash> git clone https://github.com/vesoft-inc/nebula.git
    bash> cd nebula && ./build_dep.sh N

    有問題請在 GitHub 或者微信公眾號上留言。

    附錄

    • Nebula Graph:一個開源的分佈式圖數據庫
    • GitHub:
    • 知乎:
    • 微博:

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

    小三通物流營運型態?

    ※快速運回,大陸空運推薦?

  • 一文帶你深入了解 Redis 的持久化方式及其原理

    一文帶你深入了解 Redis 的持久化方式及其原理

    Redis 提供了兩種持久化方式,一種是基於快照形式的 RDB,另一種是基於日誌形式的 AOF,每種方式都有自己的優缺點,本文將介紹 Redis 這兩種持久化方式,希望閱讀本文後你對 Redis 的這兩種方式有更加全面、清晰的認識。

    RDB 快照方式持久化

    先從 RDB 快照方式聊起,RDB 是 Redis 默認開啟的持久化方式,並不需要我們單獨開啟,先來看看跟 RDB 相關的配置信息:

    ################################ SNAPSHOTTING  ################################
    #
    # Save the DB on disk:
    #
    #   save <seconds> <changes>
    #
    #   Will save the DB if both the given number of seconds and the given
    #   number of write operations against the DB occurred.
    #
    #   In the example below the behaviour will be to save:
    #   after 900 sec (15 min) if at least 1 key changed
    #   after 300 sec (5 min) if at least 10 keys changed
    #   after 60 sec if at least 10000 keys changed
    #   save ""
    # 自動生成快照的觸發機制 中間的是時間,單位秒,後面的是變更數據 60 秒變更 10000 條數據則自動生成快照
    save 900 1
    save 300 10
    save 60 10000
    
    # 生成快照失敗時,主線程是否停止寫入
    stop-writes-on-bgsave-error yes
    
    # 是否採用壓縮算法存儲
    rdbcompression yes
    
    # 數據恢復時是否檢測 RDB文件有效性
    rdbchecksum yes
    
    # The filename where to dump the DB
    # RDB 快照生成的文件名稱
    dbfilename dump.rdb
    
    # 快照生成的路徑 AOF 也是存放在這個路徑下面
    dir .

    關於 RDB 相關配置信息不多,需要我們調整的就更少了,我們只需要根據自己的業務量修改生成快照的機制和文件存放路徑即可。

    RDB 有兩種持久化方式:手動觸發自動觸發手動觸發使用以下兩個命令:

    • save:會阻塞當前 Redis 服務器響應其他命令,直到 RDB 快照生成完成為止,對於內存 比較大的實例會造成長時間阻塞,所以線上環境不建議使用

    • bgsave:Redis 主進程會 fork 一個子進程,RDB 快照生成有子進程來負責,完成之後,子進程自動結束,bgsave 只會在 fork 子進程的時候短暫的阻塞,這個過程是非常短的,所以推薦使用該命令來手動觸發

    除了執行命令手動觸發之外,Redis 內部還存在自動觸發 RDB 的持久化機制,在以下幾種情況下 Redis 會自動觸發 RDB 持久化

    • 在配置中配置了 save 相關配置信息,如我們上面配置文件中的 save 60 10000 ,也可以把它歸類為“save m n”格式的配置,表示 m 秒內數據集存在 n 次修改時,會自動觸發 bgsave。

    • 在主從情況下,如果從節點執行全量複製操作,主節點自動執行 bgsave 生成 RDB 文件併發送給從節點

    • 執行 debug reload 命令重新加載 Redis 時,也會自動觸發 save 操作

    • 默認情況下執行 shutdown 命令時,如果沒有開啟 AOF 持久化功能則自動執行 bgsave

    上面就是 RDB 持久化的方式,可以看出 save 命令使用的比較少,大多數情況下使用的都是 bgsave 命令,所以這個 bgsave 命令還是有一些東西,那接下來我們就一起看看 bgsave 背後的原理,先從流程圖開始入手:

    bgsave 命令大概有以下幾個步驟:

    • 1、執行 bgsave 命令,Redis 主進程判斷當前是否存在正在執行的 RDB/AOF 子進程,如果存在, bgsave 命令直接返回不在往下執行。
    • 2、父進程執行 fork 操作創建子進程,fork 操作過程中父進程會阻塞,fork 完成後父進程將不在阻塞可以接受其他命令。
    • 3、子進程創建新的 RDB 文件,基於父進程當前內存數據生成臨時快照文件,完成後用新的 RDB 文件替換原有的 RDB 文件,並且給父進程發送 RDB 快照生成完畢通知

    上面就是 bgsave 命令背後的一些內容,RDB 的內容就差不多了,我們一起來總結 RDB 持久化的優缺點,RDB 方式的優點

    • RDB 快照是某一時刻 Redis 節點內存數據,非常適合做備份,上傳到遠程服務器或者文件系統中,用於容災備份
    • 數據恢復時 RDB 要遠遠快於 AOF

    有優點同樣存在缺點,RDB 的缺點有

    • RDB 持久化方式數據沒辦法做到實時持久化/秒級持久化。我們已經知道了 bgsave 命令每次運行都要執行 fork 操作創建子進程,屬於重量級操作,頻繁執行成本過高。
    • RDB 文件使用特定二進制格式保存,Redis 版本演進過程中有多個格式 的 RDB 版本,存在老版本 Redis 服務無法兼容新版 RDB 格式的問題

    如果我們對數據要求比較高,每一秒的數據都不能丟,RDB 持久化方式肯定是不能夠滿足要求的,那 Redis 有沒有辦法滿足呢,答案是有的,那就是接下來的 AOF 持久化方式

    AOF 持久化方式

    Redis 默認並沒有開啟 AOF 持久化方式,需要我們自行開啟,在 redis.conf 配置文件中將 appendonly no 調整為 appendonly yes,這樣就開啟了 AOF 持久化,與 RDB 不同的是 AOF 是以記錄操作命令的形式來持久化數據的,我們可以查看以下 AOF 的持久化文件 appendonly.aof

    *2
    $6
    SELECT
    $1
    0
    *3
    $3
    set
    $6
    mykey1
    $6
    你好
    *3
    $3
    set
    $4
    key2
    $5
    hello
    *1
    $8

    大概就是長這樣的,具體的你可以查看你 Redis 服務器上的 appendonly.aof 配置文件,這也意味着我們可以在 appendonly.aof 文件中國修改值,等 Redis 重啟時將會加載修改之後的值。看似一些簡單的操作命令,其實從命令到 appendonly.aof 這個過程中非常有學問的,下面時 AOF 持久化流程圖:

    在 AOF 持久化過程中有兩個非常重要的操作:一個是將操作命令追加到 AOF_BUF 緩存區,另一個是 AOF_buf 緩存區數據同步到 AOF 文件,接下來我們詳細聊一聊這兩個操作:

    1、為什麼要將命令寫入到 aof_buf 緩存區而不是直接寫入到 aof 文件?

    我們知道 Redis 是單線程響應,如果每次寫入 AOF 命令都直接追加到磁盤上的 AOF 文件中,這樣頻繁的 IO 開銷,Redis 的性能就完成取決於你的機器硬件了,為了提升 Redis 的響應效率就添加了一層 aof_buf 緩存層, 利用的是操作系統的 cache 技術,這樣就提升了 Redis 的性能,雖然這樣性能是解決了,但是同時也引入了一個問題,aof_buf 緩存區數據如何同步到 AOF 文件呢?由誰同步呢?這就是我們接下來要聊的一個操作:fsync 操作

    2、aof_buf 緩存區數據如何同步到 aof 文件中?

    aof_buf 緩存區數據寫入到 aof 文件是有 linux 系統去完成的,由於 Linux 系統調度機制周期比較長,如果系統故障宕機了,意味着一個周期內的數據將全部丟失,這不是我們想要的,所以 Linux 提供了一個 fsync 命令,fsync 是針對單個文件操作(比如這裏的 AOF 文件),做強制硬盤同步,fsync 將阻塞直到寫入硬盤完成后返回,保證了數據持久化,正是由於有這個命令,所以 redis 提供了配置項讓我們自行決定何時進行磁盤同步,redis 在 redis.conf 中提供了appendfsync 配置項,有如下三個選項:

    # appendfsync always
    appendfsync everysec
    # appendfsync no
    • always:每次有寫入命令都進行緩存區與磁盤數據同步,這樣保證不會有數據丟失,但是這樣會導致 redis 的吞吐量大大下降,下降到每秒只能支持幾百的 TPS ,這違背了 redis 的設計,所以不推薦使用這種方式
    • everysec:這是 redis 默認的同步機制,雖然每秒同步一次數據,看上去時間也很快的,但是它對 redis 的吞吐量沒有任何影響,每秒同步一次的話意味着最壞的情況下我們只會丟失 1 秒的數據, 推薦使用這種同步機制,兼顧性能和數據安全
    • no:不做任何處理,緩存區與 aof 文件同步交給系統去調度,操作系統同步調度的周期不固定,最長會有 30 秒的間隔,這樣出故障了就會丟失比較多的數據。

    這就是三種磁盤同步策略,但是你有沒有注意到一個問題,AOF 文件都是追加的,隨着服務器的運行 AOF 文件會越來越大,體積過大的 AOF 文件對 redis 服務器甚至是主機都會有影響,而且在 Redis 重啟時加載過大的 AOF 文件需要過多的時間,這些都是不友好的,那 Redis 是如何解決這個問題的呢?Redis 引入了重寫機制來解決 AOF 文件過大的問題。

    3、Redis 是如何進行 AOF 文件重寫的?

    Redis AOF 文件重寫是把 Redis 進程內的數據轉化為寫命令同步到新 AOF 文件的過程,重寫之後的 AOF 文件會比舊的 AOF 文件占更小的體積,這是由以下幾個原因導致的:

    • 進程內已經超時的數據不再寫入文件
    • 舊的 AOF 文件含有無效命令,如 del key1、hdel key2、srem keys、set a111、set a222等。重寫使用進程內數據直接生成,這樣新的AOF文件只保 留最終數據的寫入命令
    • 多條寫命令可以合併為一個,如:lpush list a、lpush list b、lpush list c可以轉化為:lpush list a b c。為了防止單條命令過大造成客戶端緩衝區溢 出,對於 list、set、hash、zset 等類型操作,以 64 個元素為界拆分為多條。

    重寫之後的 AOF 文件體積更小了,不但能夠節約磁盤空間,更重要的是在 Redis 數據恢復時,更小體積的 AOF 文件加載時間更短。AOF 文件重寫跟 RDB 持久化一樣分為手動觸發自動觸發,手動觸發直接調用 bgrewriteaof 命令就好了,我們後面會詳細聊一聊這個命令,自動觸發就需要我們在 redis.conf 中修改以下幾個配置

    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    • auto-aof-rewrite-percentage:代表當前 AOF文件空間 (aof_current_size)和上一次重寫后 AOF 文件空間(aof_base_size)的比值,默認是 100%,也就是一樣大的時候
    • auto-aof-rewrite-min-size:表示運行 AOF 重寫時 AOF 文件最小體積,默認為 64MB,也就是說 AOF 文件最小為 64MB 才有可能觸發重寫

    滿足了這兩個條件,Redis 就會自動觸發 AOF 文件重寫,AOF 文件重寫的細節跟 RDB 持久化生成快照有點類似,下面是 AOF 文件重寫流程圖:

    AOF 文件重寫也是交給子進程來完成,跟 RDB 生成快照很像,AOF 文件重寫在重寫期間建立了一個 aof_rewrite_buf 緩存區來保存重寫期間主進程響應的命令,等新的 AOF 文件重寫完成后,將這部分文件同步到新的 AOF 文件中,最後用新的 AOF 文件替換掉舊的 AOF 文件。需要注意的是在重寫期間,舊的 AOF 文件依然會進行磁盤同步,這樣做的目的是防止重寫失敗導致數據丟失,

    Redis 持久化數據恢復

    我們知道 Redis 是基於內存的,所有的數據都存放在內存中,由於機器宕機或者其他因素重啟了就會導致我們的數據全部丟失,這也就是要做持久化的原因,當服務器重啟時,Redis 會從持久化文件中加載數據,這樣我們的數據就恢復到了重啟前的數據,在數據恢復這一塊Redis 是如何實現的?我們先來看看數據恢復的流程圖:

    Redis 的數據恢複流程比較簡單,優先恢復的是 AOF 文件,如果 AOF 文件不存在時則嘗試加載 RDB 文件,為什麼 RDB 的恢復速度比 AOF 文件快,但是還是會優先加載 AOF 文件呢?我個人認為是 AOF 文件數據更全面並且 AOF 兼容性比 RDB 強,需要注意的是當存在 RDB/AOF 時,如果數據加載不成功,Redis 服務啟動會失敗。

    最後

    目前互聯網上很多大佬都有 Redis 系列教程,如有雷同,請多多包涵了。原創不易,碼字不易,還希望大家多多支持。若文中有所錯誤之處,還望提出,謝謝。

    歡迎掃碼關注微信公眾號:「平頭哥的技術博文」,和平頭哥一起學習,一起進步。

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 蘇門答臘瀕危老虎 受困捕獸陷阱後死亡

    摘錄自2018年9月26日中央社報導

    印尼官員今天(26日)說,一頭被列為極度瀕危物種的蘇門答臘虎死屍在蘇門答臘島廖內省(Riau)的慕亞拉藍布村(Muara Lembu)附近山溝被發現,根據虎屍肚子上圍繞著陷阱裡的繩索研判,應是受困獵人所設陷阱後死亡。

    稍早,當地村民告訴保育機構說,有人看到一頭雌蘇門答臘虎受困獵人為捕獵野豬設置的陷阱。但官員趕往現場後,已不見老虎。官員隔天回到原區域搜尋,才在附近山溝尋獲。

    國際自然保育聯盟(IUCN)將蘇門答臘虎列為「極危」的瀕危動物。自然界只剩不到400頭蘇門答臘虎,環保人士說,由於蘇門答臘虎自然棲息地迅速縮減,使牠們與人類發生衝突的機率升高。

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 保護環境 越南明年起加徵汽油環保稅

    摘錄自2018年9月21日中央社報導

    為了保護和改善環境,越南政府自明年起將調漲對汽油等燃料產品的環境保護稅,其中汽油每公升環保稅將從現行收費3000越盾(約新台幣4元)提升為4000越盾。

    越南國會常務委員會昨天(20日)通過有關環境保護稅的決議,自明年起將對相關產品加徵環保稅,希望藉此保護與改善環境,減少污染物排放。

    根據這項決議,汽油每公升環保稅將從現行收費3000越盾提升為4000越盾,柴油從1500越盾升到2000越盾,燃油和潤滑油從900越盾升到2000越盾等;此外,煤炭、塑膠袋與除草劑等也被列入加徵環保稅的產品名單。

    越南國會官員指出,加徵對汽油等燃料產品的環保稅後,國家預算每年將增加15.7兆越盾,這是一筆很大的稅收,有利用於保護與改善環境。

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

    小三通物流營運型態?

    ※快速運回,大陸空運推薦?

  • 百度聯手奇瑞安徽蕪湖建首個“全無人駕駛運營區域”

    日前,百度與安徽省蕪湖市人民政府正式簽訂合作協定,雙方將在蕪湖共同建設“全無人駕駛汽車運營區域”。

    安徽省蕪湖市市長潘朝輝稱,百度正在與奇瑞聯手打造全自動駕駛汽車。奇瑞汽車有限公司董事長尹同躍也表示,首批試運營車將由奇瑞提供。數量有20-30台,均達到全自動駕駛水準。目前車輛已經完成自動駕駛改裝,即將上路測試。

    此次與蕪湖市人民政府共建的運營區域會隨著時間逐漸擴大範圍。第一階段全自動駕駛汽車會在道況簡單的有限區域進行試運營,3-5年之間擴大區域,5年之後實現全市示範。

    關於車輛具體歸屬,技術分工,第一階段運營區規模、何時啟動,以及百度、蕪湖市政府、奇瑞的具體運營角色,現場稱會在未來給出更加詳細的資訊。

    與其他進入自動駕駛的企業相比,百度是首家與地方政府企業合作進行城市道路試運營的企業。去年年底自動駕駛汽車事業部成立時,就對外公佈了全自動駕駛的3年商用,5年量產計畫。百度全自動駕駛汽車會以公共車輛的形式,選擇10個左右國內不同城市和示範區商用運營。此次與蕪湖市政府運營簽約,也包括了3年商用和5年量產的長遠規劃。

    隨著自動駕駛汽車開始進入工程化和市場化階段,和現階段大量的封閉區域和高速公路測試相比,城市是下階段測試的理想場景。就百度而言,通過城市環境的試運營,會獲得更多道路行駛資料,説明快速反覆運算技術推向市場。除此之外,累計路測經驗也將有利於百度更加貼近未來制定的自動駕駛汽車法律法規以及行駛道路與環境標準。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 呼和浩特總投資200億元新能源汽車項目正式開工

    日前,計畫總投資約200億元的內蒙古自治區呼和浩特市金山高新區新能源汽車製造專案舉行了集中開工儀式。

    該項目占地2605畝、計畫總投資約200億元,其中基礎設施、廠房投資35億元,設計建築面積102.7萬平方米,擬入駐規模以上工業企業20家以上。項目建成後,年產值預計可達500億元,提供就業崗位3萬個,將成為內蒙古新能源汽車及核心零部件產業聚集區。

    該專案採取PPP建設模式,分三期推進。目前集中開工的6個專案是首期落戶的項目,計畫於2017年1月實現部分產能投產,預計當年產值可達100億元左右,提供就業崗位6千餘個。

    呼和浩特市金山高新區新能源汽車製造專案是該市土左旗2015年引進的億元以上重點工業專案,致力於發展新能源電池、電機、電控等核心零部件生產以及整車製造等延伸產業鏈。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

    小三通物流營運型態?

    ※快速運回,大陸空運推薦?

  • 2.NioEventLoop的創建

    2.NioEventLoop的創建

    NioEventLoop的創建

    NioEventLoop是netty及其重要的組成部件,它的首要職責就是為註冊在它上的channels服務,發現這些channels上發生的新連接、讀寫等I/O事件,然後將事件轉交 channel 流水線處理。使用netty時,我們首先要做的就是創建NioEventLoopGroup,這是一組NioEventLoop的集合,類似線程與線程池。通常,服務端會創建2個group,一個叫做bossGroup,一個叫做workerGroup。bossGroup負責監聽綁定的端口,接受請求並創建新連接,初始化后交由workerGroup處理後續IO事件。

    NioEventLoop和NioEventLoopGroup的類圖

    首先看看NioEventLoop和NioEventLoopGroup的類關係圖

    類多但不亂,可以發現三個特點:

    1. 兩者都繼承了ExecutorService,從而與線程池建立了聯繫
    2. NioEventLoop繼承的都是SingleThread,NioEventLoop繼承的是MultiThread
    3. NioEventLoop還繼承了AbstractScheduledEventExecutor,不難猜出這是個和定時任務調度有關的線程池

    NioEventLoopGroup的創建

    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();

    我們先看看bossGroup和workerGroup的構造方法。

    public NioEventLoopGroup() {
        this(0);
    }
    public NioEventLoopGroup(int nThreads) {
        this(nThreads, (Executor) null);
    }
    除此之外,還有多達8種構造方法,這些構造方法可以指定5種參數:
    1、最大線程數量。如果指定為0,那麼Netty會將線程數量設置為CPU邏輯處理器數量的2倍
    2、線程工廠。要求線程工廠類必須實現java.util.concurrent.ThreadFactory接口。如果沒有指定線程工廠,那麼默認DefaultThreadFactory。
    3、SelectorProvider。如果沒有指定SelectorProvider,那麼默認的SelectorProvider為SelectorProvider.provider()。
    4、SelectStrategyFactory。如果沒有指定則默認為DefaultSelectStrategyFactory.INSTANCE
    5、RejectedExecutionHandler。拒絕策略處理類,如果這個EventLoopGroup已被關閉,那麼之後提交的Runnable任務會默認調用RejectedExecutionHandler的reject方法進行處理。如果沒有指定,則默認調用拒絕策略。

    最終,NioEventLoopGroup會重載到父類MultiThreadEventExecutorGroup的構造方法上,這裏省略了一些健壯性代碼。

    protected MultithreadEventExecutorGroup(int nThreads, Executor executor,EventExecutorChooserFactory chooserFactory, Object... args) {
        // 步驟1
        if (executor == null) {
            executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
        }
        
        // 步驟2
        children = new EventExecutor[nThreads];
        for (int i = 0; i < nThreads; i ++) {
            children[i] = newChild(executor, args);
        }    
    
        // 步驟3
        chooser = chooserFactory.newChooser(children);
    
        // 步驟4
        final FutureListener<Object> terminationListener = future -> {
            if (terminatedChildren.incrementAndGet() == children.length) {
                terminationFuture.setSuccess(null);
            }
        };
        for (EventExecutor e: children) {
            e.terminationFuture().addListener(terminationListener);
        }
    
        // 步驟5
        Set<EventExecutor> childrenSet = new LinkedHashSet<>(children.length);
        Collections.addAll(childrenSet, children);
        readonlyChildren = Collections.unmodifiableSet(childrenSet);
        }

    這裏可以分解為5個步驟,下面一步步講解

    步驟1

    第一個步驟是創建線程池executor。從workerGroup構造方法可知,默認傳進來的executor為null,所以首先創建executor。newDefaultThreadFactory的作用是設置線程的前綴名和線程優先級,默認情況下,前綴名是nioEventLoopGroup-x-y這樣的命名規則,而線程優先級則是5,處於中間位置。
    創建完newDefaultThreadFactory后,進入到ThreadPerTaskExecutor。它直接實現了juc包的線程池頂級接口,從構造方法可以看到它只是簡單的把factory賦值給自己的成員變量。而它實現的接口方法調用了threadFactory的newThread方法。從名字可以看出,它構造了一個thread,並立即啟動thread。

    public ThreadPerTaskExecutor(ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
    }
    @Override
    public void execute(Runnable command) {
        threadFactory.newThread(command).start();
    }    

    那麼我們回過頭來看下DefaultThreadFactory的newThread方法,發現他創建了一個FastThreadLocalThread。這是netty自定義的一個線程類,顧名思義,netty認為它的性能更快。關於它的解析留待以後。這裏步驟1創建線程池就完成了。總的來說他與我們通常使用的線程池不太一樣,不設置線程池的線程數和任務隊列,而是來一個任務啟動一個線程。(問題:那任務一多豈不是直接線程爆炸?)

    @Override
    public Thread newThread(Runnable r) {
        Thread t = newThread(FastThreadLocalRunnable.wrap(r), prefix + nextId.incrementAndGet());        
        return t;
    }
    protected Thread newThread(Runnable r, String name) {
        return new FastThreadLocalThread(threadGroup, r, name);
    }

    步驟2

    步驟2是創建workerGroup中的NioEventLoop。在示例代碼中,傳進來的線程數是0,顯然不可能真的只創建0個nioEventLoop線程。在調用父類MultithreadEventLoopGroup構造函數時,對線程數進行了判斷,若為0,則傳入默認線程數,該值默認為2倍CPU核心數

    protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
        super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
    }
    // 靜態代碼塊初始化DEFAULT_EVENT_LOOP_THREADS
    static {
        DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads",     NettyRuntime.availableProcessors() * 2));
    }    

    接下來是通過newChild方法為每一個EventExecutor創建一個對應的NioEventLoop。這個方法傳入了一些args到NioEventLoop中,前三個是在NioEventLoopGroup創建時傳過來的參數。默認值見上文

    1. SlectorProvider.provider, 用於創建 Java NIO Selector 對象;
    2. SelectStrategyFactory, 選擇策略工廠;
    3. RejectedExecutionHandlers, 拒絕執行處理器;
    4. EventLoopTaskQueueFactory,任務隊列工廠,默認為null;

    進入NioEventLoop的構造函數,如下:

    NioEventLoop構造函數
    NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
                     SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler,
                     EventLoopTaskQueueFactory queueFactory) {
            super(parent, executor, false, newTaskQueue(queueFactory), newTaskQueue(queueFactory),
                    rejectedExecutionHandler);
            if (selectorProvider == null) {
                throw new NullPointerException("selectorProvider");
            }
            if (strategy == null) {
                throw new NullPointerException("selectStrategy");
            }
            provider = selectorProvider;
            final SelectorTuple selectorTuple = openSelector();
            selector = selectorTuple.selector;
            unwrappedSelector = selectorTuple.unwrappedSelector;
            selectStrategy = strategy;
        }
    // 父類構造函數    
    protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor,
                                            boolean addTaskWakesUp, Queue<Runnable> taskQueue,
                                            RejectedExecutionHandler rejectedHandler) {
        super(parent);
        this.addTaskWakesUp = addTaskWakesUp;
        this.maxPendingTasks = DEFAULT_MAX_PENDING_EXECUTOR_TASKS;
        this.executor = ThreadExecutorMap.apply(executor, this);
        this.taskQueue = ObjectUtil.checkNotNull(taskQueue, taskQueue");
        rejectedExecutionHandler = ObjectUtil.checkNotNullrejectedHandler, "rejectedHandler");
    }    

    首先調用一個newTaskQueue方法創建一個任務隊列。這是一個mpsc即多生產者單消費者的無鎖隊列。之後調用父類的構造函數,在父類的構造函數中,將NioEventLoopGroup設置為自己的parent,並通過匿名內部類創建了這樣一個Executor————通過ThreadPerTaskExecutor執行傳進來的任務,並且在執行時將當前線程與NioEventLoop綁定。其他屬性也一一設置。
    在nioEventLoop構造函數中,我們發現創建了一個selector,不妨看一看netty對它的包裝。

    unwrappedSelector = provider.openSelector();
    if (DISABLE_KEY_SET_OPTIMIZATION) {
        return new SelectorTuple(unwrappedSelector);
    }

    首先看到netty定義了一個常量DISABLE_KEY_SET_OPTIMIZATION,如果這個常量設置為true,也即不對keyset進行優化,則直接返回未包裝的selector。那麼netty對selector進行了哪些優化?

    final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
    
    final class SelectedSelectionKeySet extends AbstractSet<SelectionKey> {
    
        SelectionKey[] keys;
        int size;
    
        SelectedSelectionKeySet() {
            keys = new SelectionKey[1024];
        }
    } 

    往下,我們看到了一個叫做selectedSelectionKeySet的類,點進去可以看到,它繼承了AbstractSet,然而它的成員變量卻讓我們想到了ArrayList,再看看它定義的方法,除了不支持remove和contains外,活脫脫一個簡化版的ArrayList,甚至也支持擴容。
    沒錯,netty確實通過反射的方式,將selectionKey從Set替換為了ArrayList。仔細一想,卻又覺得此番做法有些道理。眾所周知,雖然HashSet和ArrayList隨機查找的時間複雜度都是o(1),但相比數組直接通過偏移量定位,HashSet由於需要Hash運算,時間消耗上又稍稍遜色了些。再加上使用場景上,都是獲取selectionKey集合然後遍歷,Set去重的特性完全用不上,也無怪乎追求性能的netty想要替換它了。

    步驟3

    創建完workerGroup的NioEventLoop后,如何挑選一個nioEventLoop進行工作是netty接下來想要做的事。一般來說輪詢是一個很容易想到的方案,為此需要創建一個類似負載均衡作用的線程選擇器。當然追求性能到喪心病狂的netty是不會輕易滿足的。我們看看netty在這樣常見的方案里又做了哪些操作。

    public EventExecutorChooser newChooser(EventExecutor[] executors) {
        if (isPowerOfTwo(executors.length)) {
            return new PowerOfTwoEventExecutorChooser(executors);
        } else {
            return new GenericEventExecutorChooser(executors);
        }
    }
    // PowerOfTwo
    public EventExecutor next() {
        return executors[idx.getAndIncrement() & executors.length - 1];
    }
    // Generic
    public EventExecutor next() {
        return executors[Math.abs(idx.getAndIncrement() % executors.length)];
    }

    可以看到,netty根據workerGroup內線程的數量採取了2種不同的線程選擇器,當線程數x是2的冪次方時,可以通過&(x-1)來達到對x取模的效果,其他情況則需要直接取模。這與hashmap強制設置容量為2的冪次方有異曲同工之妙。

    步驟4

    步驟4就是添加一些保證健壯性而添加的監聽器了,這些監聽器會在EventLoop被關閉后得到通知。

    步驟5

    創建一個只讀的NioEventLoop線程組

    到此NioEventLoopGroup及其包含的NioEventLoop組就創建完成了

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 理解Spark SQL(一)—— CLI和ThriftServer

    理解Spark SQL(一)—— CLI和ThriftServer

    Spark SQL主要提供了兩個工具來訪問hive中的數據,即CLI和ThriftServer。前提是需要Spark支持Hive,即編譯Spark時需要帶上hive和hive-thriftserver選項,同時需要確保在$SPARK_HOME/conf目錄下有hive-site.xml配置文件(可以從hive中拷貝過來)。在該配置文件中主要是配置hive metastore的URI(Spark的CLI和ThriftServer都需要)以及ThriftServer相關配置項(如hive.server2.thrift.bind.host、hive.server2.thrift.port等)。注意如果該台機器上同時運行有Hive ThriftServer和Spark ThriftServer,則hive中的hive.server2.thrift.port配置的端口與spark中的hive.server2.thrift.port配置的端口要不一樣,避免同時啟動時發生端口衝突。

    啟動CLI和ThriftServer之前都需要先啟動hive metastore。執行如下命令啟動:

    [root@BruceCentOS ~]# nohup hive –service metastore &

    成功啟動后,會出現一個RunJar的進程,同時會監聽端口9083(hive metastore的默認端口)。

     

     

     先來看CLI,通過spark-sql腳本來使用CLI。執行如下命令:

    [root@BruceCentOS4 spark]# $SPARK_HOME/bin/spark-sql –master yarn

    上述命令執行後會啟動一個yarn client模式的Spark程序,如下圖所示:

      同時它會連接到hive metastore,可以在隨後出現的spark-sql>提示符下運行hive sql語句,比如:

      其中每輸入並執行一個SQL語句相當於執行了一個Spark的Job,如圖所示:

      也就是說執行spark-sql腳本會啟動一個yarn clien模式的Spark Application,而後出現spark-sql>提示符,在提示符下的每個SQL語句都會在Spark中執行一個Job,但是對應的都是同一個Application。這個Application會一直運行,可以持續輸入SQL語句執行Job,直到輸入“quit;”,然後就會退出spark-sql,即Spark Application執行完畢。

     

    另外一種更好地使用Spark SQL的方法是通過ThriftServer,首先需要啟動Spark的ThriftServer,然後通過Spark下的beeline或者自行編寫程序通過JDBC方式使用Spark SQL。

    通過如下命令啟動Spark ThriftServer:

    [root@BruceCentOS4 spark]# $SPARK_HOME/sbin/start-thriftserver.sh –master yarn

    執行上面的命令后,會生成一個SparkSubmit進程,實際上是啟動一個yarn client模式的Spark Application,如下圖所示:

      而且它提供一個JDBC/ODBC接口,用戶可以通過JDBC/ODBC接口連接ThriftServer來訪問Spark SQL的數據。具體可以通過Spark提供的beeline或者在程序中使用JDBC連接ThriftServer。例如在啟動Spark ThriftServer后,可以通過如下命令使用beeline來訪問Spark SQL的數據。

    [root@BruceCentOS3 spark]# $SPARK_HOME/bin/beeline -n root -u jdbc:hive2://BruceCentOS4.Hadoop:10003

     上述beeline連接到了BruceCentOS4上的10003端口,也就是Spark ThriftServer。所有連接到ThriftServer的客戶端beeline或者JDBC程序共享同一個Spark Application,通過beeline或者JDBC程序執行SQL相當於向這個Application提交並執行一個Job。在提示符下輸入“!exit”命令可以退出beeline。

    最後,如果要停止ThriftServer(即停止Spark Application),需要執行如下命令:

    [root@BruceCentOS4 spark]# $SPARK_HOME/sbin/stop-thriftserver.sh

     

     綜上所述,在Spark SQL的CLI和ThriftServer中,比較推薦使用後者,因為後者更加輕量,只需要啟動一個ThriftServer(對應一個Spark Application)就可以給多個beeline客戶端或者JDBC程序客戶端使用SQL,而前者啟動一個CLI就啟動了一個Spark Application,它只能給一個用戶使用。

     

     

     

     

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

    小三通物流營運型態?

    ※快速運回,大陸空運推薦?