如何使用pipeline function獲得實時輸出

2021-01-18 中關村在線

很多人都知道,在普通的函數中,使用dbms_output輸出的信息,需要在

伺服器

執行完整個函數後一次性的返回給客戶端。但你如果需要在客戶端實時的輸出函數執行過程中的一些信息,在Oracle 9i以後則可以使用管道函數(pipeline function)。

PIPELINED(關鍵字)表明這是一個管道函數,管道函數的返回值類型必須為集合,在函數中,PIPE ROW語句被用來返回該集合的單個元素,函數則以一個空的RETURN語句結束,以表明它已經完成。


create or replace type MsgType as table of varchar2(4000);/create or replace function f_pipeline_testreturn MsgTypePIPELINEDasbegin for i in 1 .. 10 loop pipe row( 'Iteration ' || i || ' at ' || systimestamp ); dbms_lock.sleep(1); end loop; pipe row( 'All done!' ); return;end;/

在sql*plus中執行該函數,大家需要首先設置arraysize為1,否則伺服器會按照默認的15來向客戶端返回信息,這會影響我們的測試效果。

SQL> set arraysize 1SQL> select * from table( f_pipeline_test );COLUMN_VALUE---Iteration 1 at 14-FEB-08 02.13.18.273988000 PM +08:00Iteration 2 at 14-FEB-08 02.13.19.275988000 PM +08:00Iteration 3 at 14-FEB-08 02.13.20.277767000 PM +08:00Iteration 4 at 14-FEB-08 02.13.21.279591000 PM +08:00Iteration 5 at 14-FEB-08 02.13.22.281366000 PM +08:00Iteration 6 at 14-FEB-08 02.13.23.283189000 PM +08:00Iteration 7 at 14-FEB-08 02.13.24.283965000 PM +08:00Iteration 8 at 14-FEB-08 02.13.25.285785000 PM +08:00Iteration 9 at 14-FEB-08 02.13.26.286570000 PM +08:00Iteration 10 at 14-FEB-08 02.13.27.288387000 PM +08:00All done!

11 rows selected.

如果要在pipeline中執行DML操作,則必須使用自治事務,否則會報ORA-14551錯誤

create or replace function f_pipeline_testdmlreturn MsgTypePIPELINEDasbegin for i in 1 .. 10 loop insert into test values(1); pipe row( 'insert into test values( ' || i || ') success at ' || systimestamp ); dbms_lock.sleep(1); end loop; pipe row( 'All done!' ); return;end;/SQL> select * from table( f_pipeline_testdml ); select * from table( f_pipeline_testdml ) *ERROR at line 1:ORA-14551: cannot perform a DML operation inside a queryORA-06512: at "NING.F_PIPELINE_TESTDML", line 8create or replace function f_pipeline_testdmlreturn MsgTypePIPELINEDaspragma autonomous_transaction;beginfor i in 1 .. 10loopinsert into test values(1);commit;pipe row( 'insert values ' || i || ' success at ' || systimestamp );dbms_lock.sleep(1);end loop;pipe row( 'All done!' );return;end;/SQL> select * from table( f_pipeline_testdml );COLUMN_VALUEinsert values 1 success at 14-FEB-08 02.16.47.855158000 PM +08:00insert values 2 success at 14-FEB-08 02.16.48.865559000 PM +08:00insert values 3 success at 14-FEB-08 02.16.49.867377000 PM +08:00insert values 4 success at 14-FEB-08 02.16.50.873154000 PM +08:00insert values 5 success at 14-FEB-08 02.16.51.874942000 PM +08:00insert values 6 success at 14-FEB-08 02.16.52.880781000 PM +08:00insert values 7 success at 14-FEB-08 02.16.53.882543000 PM +08:00insert values 8 success at 14-FEB-08 02.16.54.894348000 PM +08:00insert values 9 success at 14-FEB-08 02.16.55.896153000 PM +08:00insert values 10 success at 14-FEB-08 02.16.56.901904000 PM +08:00All done!11 rows selected.

在Oracle 9205及其之後的版本中,在pipeline function中使用自治事務,則必須在pipe row之前提交或者回滾事務,否則會報ORA-06519錯誤。

create or replace function f_pipeline_testdmlreturn MsgTypePIPELINEDaspragma autonomous_transaction;beginfor i in 1 .. 10loopinsert into test values(1);pipe row( 'insert values ' || i || ' success at ' || systimestamp );dbms_lock.sleep(1);end loop;pipe row( 'All done!' );commit;return;end;/SQL> select * from table( f_pipeline_testdml );select * from table( f_pipeline_testdml ) *ERROR at line 1:ORA-06519: active autonomous transaction detected and rolled backORA-06512: at "NING.F_PIPELINE_TESTDML", line 10

此處是由於在9205中修復Bug 2711518導致了自治事務的行為有所改變。如果系統從9205之前的版本升級到之後的版本,需要保證pipeline function的行為和以前版本一致,Oracle提供了一個10946事件來設置和以前版本的兼容性,如果在管道函數中使用了select for update的cursor,則必須設置event回歸以前的特性,否則即使在pipe row之前commit也會導致出現ORA-1002錯誤。

ALTER SYSTEM SET EVENT = "10946 trace name context forever, level 8" scope=spfile;

    正在連接到 (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))

    LISTENER 的 STATUS

    ----

    別名 LISTENER

    版本 TNSLSNR for 32-bit Windows: Version 10.2.0.1.0 - Produ

    ction

    啟動日期 03-12月-2007 09:29:47

    正常運行時間 0 天 0 小時 49 分 50 秒

    跟蹤級別 off

    安全性 ON: Local OS Authentication

    SNMP OFF

    監聽程序日誌文件 e:oracleproduct10.2.0db_1networkloglistener.log

    監聽端點概要……

    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=xys)(PORT=1521)))

    服務摘要……

    服務 "TEST2.COM" 包含 1 個例程。

    例程 "inst_test", 狀態 READY, 包含此服務的 1 個處理程序……

    服務 "TEST3.COM" 包含 1 個例程。

    例程 "inst_test", 狀態 READY, 包含此服務的 1 個處理程序……

    服務 "test1.COM" 包含 1 個例程。

    例程 "inst_test", 狀態 READY, 包含此服務的 1 個處理程序……

    服務 "test1_XPT.COM" 包含 1 個例程。

    例程 "inst_test", 狀態 READY, 包含此服務的 1 個處理程序……

    命令執行成功

    SQL> show parameter service_names

    NAME TYPE VALUE

    - -

    service_names string TEST2, TEST3

    我們發現service_names的值是TEST2, TEST3,但是lsnrctl status顯示的結果中包含了「

    服務 "test1.COM" 包含 1 個例程。

    例程 "inst_test", 狀態 READY, 包含此服務的 1 個處理程序……「

    2、instnace_name 實例名

    SQL> show parameter instance_name

    NAME TYPE VALUE

    - -

    instance_name string inst_test

    instance_name除了動態註冊監聽用到之外,到目前為止我沒有發現其他用處,也許oracle用它來區分各個實例?不過相信僅僅通過instance_name也不能完全區分,至少也的用到sid吧,看看上面顯示出來的動態註冊監聽中的信息,其中inst_test就是instance_name

    3、SID:System Identifier

    The SID identifies the instance's shared memory on a host, but may not uniquely distinguish this instance

    from other instances

    doc上把sid解釋為在host上用sid來標示實例的共享內存的,可見sid主要是和os打交道的。

    sid可以通過如下語句在庫中查詢:

    SQL> select instance_name from v\$instance;

    INSTANCE_NAME

    -

    tsid

    儘管v\$instance中欄位 instance_name 看起來是實例名,但是實際上存儲的是sid,在win下sid不能重複,不管oracle_home是否相同,相同當然不行,主要是不同也不行,這裡的不同是針對unix/linux而言的,在unix/linux下只要不同版本的oracle安裝在不同的oracle_home下就可以創建相同sid的實例,但是win下不可以,這不是由oracle決定的,主要是受到windows服務的限制,在服務中不能存在服務名相同的oracle服務,服務名是由如下格式組成的:OracleServiceSID,因為服務名中包括了sid,所以sid如果相同了,服務名就相同了,這是windows所不允許的。因此在win下無法創建相同sid的不同實例。

    4、service_names 服務名

    服務名是複數,大家看好了,意味著service_names 可以是多個值,這裡的服務名除了在動態註冊的監聽中被用到之外,沒有發現其它用處,還有其它用處大家可以補充,dataguard中建議大家在primary,standby上使用相同的service_names,這樣可能便於儘可能的實現透明切換,前提是如果沒有配置靜態靜聽的話,當然如果配置了靜態註冊的監聽在primary,standby上也務必保持在listener中要求輸入的服務名相同,還是那句話,儘可能的實現透明切換。下面查詢可以顯示service_names:

    SQL> show parameter service_names

    NAME TYPE VALUE

    - -

    service_names string TEST2, TEST3

    這裡我指定了2個值test2,test3,再來看看動態註冊的監聽是如何使用服務名的,監聽的部分狀態信息如下:

    服務 "TEST2.COM" 包含 1 個例程。

    例程 "inst_test", 狀態 READY, 包含此服務的 1 個處理程序……

    服務 "TEST3.COM" 包含 1 個例程。

    例程 "inst_test", 狀態 READY, 包含此服務的 1 個處理程序……

    這裡我們看到顯示出來的服務名有後綴com,是因為我設置了db_domain

    5、db_domain 資料庫域名

    SQL> show parameter db_domain

    NAME TYPE VALUE

    - -

    db_domain string COM

    doc上說它被"."分割,包括句點最多128個字符,沒改過這麼長的,不知道,沒有驗證過,誰想驗證就驗證一下,db_domain 的作用主要是用在分布式資料庫中,分布式事務的各個資料庫應該有db_domain ,但是要求他們是否相同,doc上沒說,我也不知道,之前單位開發有分布式環境,但是當時沒有注意過,不過高級複製中要同步的對象所在的資料庫是無論如何也要設置db_domain 的,是否要求相同也不得而知了,我在配置複製的時候把db_domain 設置為相同的了。介紹db_domain 的另一個用途就是在同一個os域中如果要創建同名db_name的資料庫時建議最好讓具有相同db_name的資料庫具有不同的db_domain,以保證在同一個域中global_name是唯一的。doc上也是這樣建議的:Oracle recommends that you specify DB_DOMAIN as a unique string for all databases in a domain

    當指定了db_domain的時候,在創建db link時會自動在db_link的後面加上db_domain(doc:

    If you omit the domains from the name of a database link, Oracle expands the name by qualifying the database with the domain of your local database as it currently exists in the data dictionary, and then stores the link name in the data dictionary. The characters valid in a database domain name are: alphanumeric characters, underscore (_), and number sign (#)。

    ),9i好像記得是這樣的,但是10g我驗證了一下不是:

    SQL> create database link dbl_test using 'orcl';

    資料庫連結已創建。

    SQL> select db_link from dba_db_links;

    DB_LINK

    -

    DBL

    DBL_TEST

    ORCL

    還有一點需要主要的是:You must set this parameter for every instance, and multiple instances must have the same value in Real Application Clusters

    6、global_name 全局資料庫名

    global_name 是由db_name.db_domain構成的,doc如下:

 以下是引用片段:
  Understanding How Global Database Names Are Formed
  A global database name is formed from two components: a database name and a domain. The database name and the domain name are determined by the following initialization parameters at database creation:
  Component Parameter Requirements Example
  Database name DB_NAME Must be eight characters or less. sales
  Domain containing the database DB_DOMAIN Must follow standard Internet conventions. Levels in domain names must be separated by dots and the order of domain names is from leaf to root, left to right. us.acme.com

    但是通過驗證發現oracle並沒有把db_name.db_domain和global_name 同步起來,不知道為什麼?global_name oracle是通過提供了一個view,sys.global_name,該試圖是源於props\$的,可以查看創建view的腳本,最終我們訪問的是一個public synonym global_name:

以下是引用片段:
  SQL> select * from global_name;
  GLOBAL_NAME
  ----
  test1

    按照doc的意思,我上面看到的查詢結果應該是test1.com才對,這是我的疑問,好久了?

    不過我們也可以修改global_name:

    SQL> alter database rename global_name to test1.com;

    資料庫已更改。

 以下是引用片段:
  SQL> select * from global_name;
  GLOBAL_NAME
  
  TEST1.COM
  SQL> alter database rename global_name to test123.com;

資料庫已更改。

 以下是引用片段:
  SQL> select * from global_name;
  GLOBAL_NAME
  
  TEST123.COM
  SQL>

    需要注意的是一旦加上了域就不能通過上面的命令去掉了,如:

    SQL> alter database rename global_name to test123.com;

    資料庫已更改。

 以下是引用片段:
  SQL> select * from global_name;
  GLOBAL_NAME
  
  TEST123.COM
  SQL> alter database rename global_name to test1;

資料庫已更改。

 以下是引用片段:
  SQL> select * from global_name;
  GLOBAL_NAME
  
  TEST1.COM
  SQL> alter database rename global_name to test123;

資料庫已更改。

 以下是引用片段:
  SQL> select * from global_name;
  GLOBAL_NAME
  
  TEST123.COM
  SQL>

    不過可以直接update global_name 或者props\$來去掉後綴:

    SQL> update global_name set global_name='test1';

    已更新 1 行。

    SQL> commit;

    提交完成。

以下是引用片段:
  SQL> select * from global_name;
  GLOBAL_NAME
  ---
  test1
  SQL>

    global_name 的作用主要也是用在Distributed Database中,我只在高級複製中用過global_name

    詳細的內容也可以參考下面的連接:

    [url=http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/ds_admin.htm#sthref4096]http://download.oracle.com/docs/ …… dmin.htm#sthref4096[/url]

    7、global_names 是一個布爾值

    為什麼要提它,是應為global_names和global_name看起來很相似,global_names的作用是創建db link時是否強制使用遠程資料庫的global_name,如果global_names=true,則db link name必須要求是remote database的global_name,否則創建之後db link 不能連同,測試如下,預設值是false.

 以下是引用片段:
  SQL> show parameter global_names
  NAME TYPE VALUE
  - - 
  global_names boolean TRUE
  SQL> select count(*) from t_emp@dbl;
  select count(*) from t_emp@dbl

    第 1 行出現錯誤:

    ORA-02085: 資料庫連結 DBL 連接到 ORCL

  SQL> col db_link format a10
  SQL> col host format a10
  SQL> col owner format a10
  SQL> col username format a10
  SQL> select * from dba_db_links;
  OWNER DB_LINK USERNAME HOST CREATED
   ----
  SYS DBL TEST orcl 01-12月-07
  SYS ORCL TEST orcl 01-12月-07
  SQL> select count(*) from t_emp@orcl;
  COUNT(*)
  
  4
  SQL>

    8、在通過netmanager配置靜態監聽註冊時,需要輸入的全局資料庫名(GLOBAL_DBNAME )到底應該輸入什麼?而通過netmanager配置網絡服務命名(tns)是需要輸入的服務名(SERVICE_NAME )又是什麼?

listener.ora內容如下:

  SID_LIST_LISTENER =
  (SID_LIST =
  (SID_DESC =
  (GLOBAL_DBNAME = test)
  (ORACLE_HOME = E:oracleproduct10.2.0db_1)
  (SID_NAME = tsid)
  )
  )
  LISTENER =
  (DESCRIPTION =
  (ADDRESS = (PROTOCOL = TCP)(HOST = xys)(PORT = 1521))
  )

    tnsnames.ora內容如下:

  TEST =
  (DESCRIPTION =
  (ADDRESS_LIST =
  (ADDRESS = (PROTOCOL = TCP)(HOST = xys)(PORT = 1521))
  )
  (CONNECT_DATA =
  (SERVICE_NAME = test)
  )
  )

    這裡明確的告訴大家,配置靜態監聽註冊時,需要輸入的全局資料庫名(GLOBAL_DBNAME )輸入什麼都可以,只要保證listerner.ora中的GLOBAL_DBNAME和tnsnames.ora中的SERVICE_NAME保持一致就可以,下面通過試驗看看效果:

    值得主要的是GLOBAL_DBNAME = test,而此時資料庫的db_name和global_name以及service_names分別如下顯示:

    SQL> show parameter db_name

    NAME TYPE VALUE

    - -

    db_name string test1

    SQL> select *from global_name;

    GLOBAL_NAME

    

    test1

    SQL> alter database rename global_name to abcd.yu;

    資料庫已更改。

    SQL> select *from global_name;

    GLOBAL_NAME

    

    ABCD.YU

    SQL>

    SQL> show parameter service_names

    NAME TYPE VALUE

    - -

    service_names string TEST2, TEST3

    SQL>

    而我在配置listener和tnsnames時提供的test和db_name,globla_name,service_name沒有任何關係,然後看看tnsping的效果:

    C:>tnsping test

    已使用 TNSNAMES 適配器來解析別名

    Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)

    (HOST = xys)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = test)))

    OK (30 毫秒)

    C:>

    9、db_unique_name

    DB_UNIQUE_NAME是10g的參數,在配置dataguard環境時必須為處於dg環境中每個db設置一個唯一值,在沒有DB_UNIQUE_NAME參數之前,在同一臺機器上搭建dg時必須使用參數LOCK_NAME_SPACE在standby參數文件中,10g

    有了參數db_unique_name,LOCK_NAME_SPACE已經被廢棄!

 

相關焦點

  • FATE1.0重磅發布:首個可視化聯邦學習產品與聯邦pipeline生產服務...
    作為全球首個聯邦學習工業級技術框架,FATE支持聯邦學習架構體系與各種機器學習算法的安全計算,實現了基於同態加密和多方計算(MPC)的安全計算協議,能夠幫助多個組織機構在符合數據安全和政府法規前提下,有效和協作地進行數據使用和聯合建模。
  • PICRUSt2 使用指南
    picrust2_pipeline.py -s study_seqs.fna -i study_seqs.biom -o picrust2_out_pipeline -p 1所有輸出文件位於 picrust2_out_pipeline 文件夾中。這些是默認輸出,若指定其他功能資料庫或自定義參考資料庫( 例如非16S擴增子參考數據集 ),則輸出將有所不同。
  • 如何使用PySpark來利用機器學習模型對流數據進行預測?
    使用PySpark對流數據進行情感分析什麼是流數據?社交媒體產生的數據是驚人的。你敢於想像存儲所有數據需要些什麼嗎?這是一個複雜的過程!因此,在深入探討本文的Spark方面之前,先來理解什麼是流數據。流數據沒有離散的開始或結束。這些數據是每秒從數千個數據源中生成的,它們需要儘快進行處理和分析。大量流數據需要實時處理,例如Google搜索結果。
  • 將Docker與pipeline一起使用
    Jenkinsfile(聲明性管道)pipeline { agent { docker { image 'node:7-alpine' } } stages { stage('Test') { steps { sh 'node --version' } } }}切換腳本管道 (高級)當管道執行時,Jenkins將自動啟動指定的容器並在其中執行定義的步驟:
  • 陳丹琦新作:關係抽取新SOTApipeline挫敗joint
    近期研究多採用 joint 方式建模兩個子任務,而陳丹琦等人新研究提出一種簡單高效的 pipeline 方法,在多個基準上獲得了新的 SOTA 結果。雖然簡單,但這一 pipeline 模型非常有效:在 3 個標準基準(ACE04、ACE05、SciERC)上,使用相同的預訓練編碼器,該模型優於此前所有的 joint 模型。
  • 陳丹琦新作:關係抽取新SOTA,用pipeline方式挫敗joint模型
    近期研究多採用 joint 方式建模兩個子任務,而陳丹琦等人新研究提出一種簡單高效的 pipeline 方法,在多個基準上獲得了新的 SOTA 結果。端到端關係抽取旨在識別命名實體,同時抽取其關係。近期研究大多採取 joint 方式建模這兩項子任務,要麼將二者統一在一個結構化預測網絡中,要麼通過共享表示進行多任務學習。
  • Unroll & Pipeline | 細粒度並行優化的完美循環
    HLS 優化設計的最關鍵指令有兩個:一個是流水線 (pipeline) 指令,一個是數據流(dataflow) 指令。正確地使用好這兩個指令能夠增強算法地並行性,提升吞吐量,降低延遲但是需要遵循一定的代碼風格。
  • China, Russia launch gas pipeline
    The two presidents, Xi in Beijing and Putin in Sochi, Russia, greeted each other, and Xi expressed gratitude toward the workers building the pipeline.
  • Google軟體工程師解讀:深度學習的activation function哪家強?
    TLDR (or the take-away)優先使用ReLU (Rectified Linear Unit) 函數作為神經元的activation function:背景深度學習的基本原理是基於人工神經網絡,信號從一個神經元進入,經過非線性的activation function,傳入到下一層神經元;再經過該層神經元的activate,繼續往下傳遞,如此循環往復,直到輸出層。
  • Pipeline 和 Transformer
    因此,在建立機器學習模型時,學習如何有效地使用這些方法是至關重要的。在深入討論之前,我們先從兩個方面著手:Transformer:Transformer是指具有fit()和transform()方法的對象,用於清理、減少、擴展或生成特徵。簡單地說,transformers幫助你將數據轉換為機器學習模型所需的格式。
  • 使用Flask部署機器學習模型
    但後來我遇到了一個障礙——我到底該如何把我的模型交給我的客戶呢?我不能給他們一個Jupyter notebook!我所學的一切都集中在模型構建組件上。沒有多少人會談論如何部署你的機器學習模型。把你的模型投入生產意味著什麼?它需要什麼?這些都是每個數據科學家需要回答的關鍵的職業定義問題。這就是為什麼我決定寫下這個教程來演示如何使用Flask來部署機器學習模型。
  • 用HTML5把Canvas緩衝區內容輸出到屏幕
    我會儘量簡要說明如何使用HTML5 canvas元素和JavaScript創建簡單的遊戲。本教程將省略一些代碼,但絕非故意。您可以隨時查看我的遊戲演示。  之前,我們使用使用HTML編寫網頁遊戲,現在卻在使用HTML5。那麼兩者有區別嗎?元素用來創建客戶端遊戲時非常方便。針對客戶端遊戲編程,Canvas和JavaScript使用起來非常簡單。
  • Implicit Function微分詳解
    Implicit function
  • 尋找同源基因工具OrthoMCL與OrthoFinder的安裝與使用
    Github上的一款工具OrthoMCL Pipeline (https://github.com/apetkau/orthomcl-pipeline) 能夠很好的解決這些繁瑣的步驟和分析過程中的繁瑣參數設置。這個工具的安裝過程雖然複雜,但是在最後的使用是舒爽的很。
  • 使用FPGA實現高效並行實時上採樣
    其實,上採樣和下採樣都是對數位訊號進行重採,重採的採樣率與原來獲得該數位訊號的採樣率比較,大於原信號的稱為上採樣,小於的則稱為下採樣。上採樣是下採樣的逆過程,也稱增取樣或內插。本文引用地址:http://www.eepw.com.cn/article/201610/308355.htm本文介紹一種使用Virtex-6器件和免費WebPACK工具實現實時四倍上採樣的方法。
  • 「首席看應用架構」輪詢,SSE 和WebSocket,如何選擇合適的?
    構建實時Web應用程式有點挑戰,我們需要考慮如何將數據從伺服器發送到客戶端。 能夠「主動」實現這一功能的技術已經存在了很長時間,並且僅限於兩種通用方法:客戶端請求或伺服器請求。;});一旦我們從GitHub事件API獲得數據,就可以在建立連接後將其流式傳輸到客戶端。
  • 如何使用模擬示波器檢測信號發生器輸出信號
    如何使用模擬示波器檢測信號發生器輸出信號,今天儀表工作在線的陳工與大家簡單講解下,使用模擬示波器檢測信號發生器輸出信號的操作方法:1、首先連接好信號發生器電源,打開信號發生器的電源開關,此時信號發生器的指示燈亮,信號發生器啟動。
  • NLP中的預處理:使用python進行文本歸一化
    →去除大寫字母(通常,使用小寫單詞可獲得更好的結果。但是,在某些情況下,大寫字母對於提取信息(例如名稱和位置)非常重要)。→刪除或替換特殊字符/表情符號(例如:刪除主題標籤)。→替換單詞縮寫(英語中很常見;例如:「我」→「我是」)。
  • 如何在 Kubernetes 上配置 Jenkins?
    作為一款被廣泛使用的開源CI伺服器,Jenkins提供了數百個插件,能夠為我們項目的構建、部署和自動化提供有力支持。接下來,我們將:1.使用minikube創建一個Kubernetes集群(這步不是必須的,如果你已經有Kubernetes集群了的話,可以跳過這一步)。2.為Jenkins創建命名空間和持久卷。