騰訊云mysql架構_一個數據庫存儲架構的獨白

本文由云+社區發表

本文作者:許中清,騰訊云自研數據庫CynosDB的分布式存儲CynosStore負責人。從事數據庫內核開發、數據庫產品架構和規劃。曾就職于華為,2015年加入騰訊,參與過TBase(PGXZ)、CynosDB等數據庫產品研發。專注于關系數據庫、數據庫集群、新型數據庫架構等領域。目前擔任CynosDB的分布式存儲CynosStore負責人。

企業IT系統遷移到公有云上已然是正在發生的趨勢。數據庫服務,作為公有云上提供的關鍵組件,是企業客戶是否愿意將自己運行多年的系統搬到云上的關鍵考量之一。另一方面,自從System R開始,關系數據庫系統已經大約四十年的歷史了。尤其是隨著互聯網的發展,業務對數據庫實例的吞吐量要求越來越高。對于很多業務來說,單個物理機器所能提供的最大吞吐量已經不能滿足業務的高速發展。因此,數據庫集群是很多IT系統繞不過去的坎。

CynosDB for PostgreSQL是騰訊云自研的一款云原生數據庫,其主要核心思想來自于亞馬遜的云數據庫服務Aurora。這種核心思想就是“基于日志的存儲”和“存儲計算分離”。同時,CynosDB在架構和工程實現上確實有很多和Aurora不一樣的地方。CynosDB相比傳統的單機數據庫,主要解決如下問題:

存算分離

存算分離是云數據庫區別于傳統數據庫的主要特點之一,主要是為了1)提升資源利用效率,用戶用多少資源就給多少資源;2)計算節點無狀態更有利于數據庫服務的高可用性和集群管理(故障恢復、實例遷移)的便利性。

存儲自動擴縮容

傳統關系型數據庫會受到單個物理機器資源的限制,包括單機上存儲空間的限制和計算能力的限制。CynosDB采用分布式存儲來突破單機存儲限制。另外,存儲支持多副本,通過RAFT協議來保證多副本的一致性。

更高的網絡利用率

通過基于日志的存儲設計思路,大幅度降低數據庫運行過程中的網絡流量。

更高的吞吐量

傳統的數據庫集群,面臨的一個關鍵問題是:分布式事務和集群吞吐量線性擴展的矛盾。也就是說,很多數據庫集群,要么支持完整的ACID,要么追求極好的線性擴展性,大部分時候魚和熊掌不可兼得。前者比如Oracle RAC,是目前市場上最成熟最完善的數據庫集群,提供對業務完全透明的數據訪問服務。但是Oracle RAC的線性擴展性卻被市場證明還不夠,因此,更多用戶主要用RAC來構建高可用集群,而不是高擴展的集群。后者比如Proxy+開源DB的數據庫集群方案,通常能提供很好的線性擴展性,但是因為不支持分布式事務,對數據庫用戶存在較大的限制。又或者可以支持分布式事務,但是當跨節點寫入比例很大時,反過來降低了線性擴展能力。CynosDB通過采用一寫多讀的方式,利用只讀節點的線性擴展來提升整個系統的最大吞吐量,對于絕大部份公有云用戶來說,這就已經足夠了。

存儲自動擴縮容

傳統關系型數據庫會受到單個物理機器資源的限制,包括單機上存儲空間的限制和計算能力的限制。CynosDB采用分布式存儲來突破單機存儲限制。另外,存儲支持多副本,通過RAFT協議來保證多副本的一致性。

更高的網絡利用率

通過基于日志的存儲設計思路,大幅度降低數據庫運行過程中的網絡流量。

更高的吞吐量

傳統的數據庫集群,面臨的一個關鍵問題是:分布式事務和集群吞吐量線性擴展的矛盾。也就是說,很多數據庫集群,要么支持完整的ACID,要么追求極好的線性擴展性,大部分時候魚和熊掌不可兼得。前者比如Oracle RAC,是目前市場上最成熟最完善的數據庫集群,提供對業務完全透明的數據訪問服務。但是Oracle RAC的線性擴展性卻被市場證明還不夠,因此,更多用戶主要用RAC來構建高可用集群,而不是高擴展的集群。后者比如Proxy+開源DB的數據庫集群方案,通常能提供很好的線性擴展性,但是因為不支持分布式事務,對數據庫用戶存在較大的限制。又或者可以支持分布式事務,但是當跨節點寫入比例很大時,反過來降低了線性擴展能力。CynosDB通過采用一寫多讀的方式,利用只讀節點的線性擴展來提升整個系統的最大吞吐量,對于絕大部份公有云用戶來說,這就已經足夠了。

下圖為CynosDB for PostgreSQL的產品架構圖,CynosDB是一個基于共享存儲、支持一寫多讀的數據庫集群。

1620CynosDB for PostgreSQL產品架構圖

圖一CynosDB for PostgreSQL產品架構圖

CynosDB基于CynosStore之上,CynosStore是一個分布式存儲,為CynosDB提供堅實的底座。CynosStore由多個Store Node和CynosStore Client組成。CynosStore Client以二進制包的形式與DB(PostgreSQL)一起編譯,為DB提供訪問接口,以及負責主從DB之間的日志流傳輸。除此之外,每個Store Node會自動將數據和日志持續地備份到騰訊云對象存儲服務COS上,用來實現PITR(即時恢復)功能。

一、CynosStore數據組織形式

CynosStore會為每一個數據庫分配一段存儲空間,我們稱之為Pool,一個數據庫對應一個Pool。數據庫存儲空間的擴縮容是通過Pool的擴縮容來實現的。一個Pool會分成多個Segment Group(SG),每個SG固定大小為10G。我們也把每個SG叫做一個邏輯分片。一個Segment Group(SG)由多個物理的Segment組成,一個Segment對應一個物理副本,多個副本通過RAFT協議來實現一致性。Segment是CynosStore中最小的數據遷移和備份單位。每個SG保存屬于它的數據以及對這部分數據最近一段時間的寫日志。

1620CynosStore 數據組織形式

圖二 CynosStore 數據組織形式

圖二中CynosStore一共有3個Store Node,CynosStore中創建了一個Pool,這個Pool由3個SG組成,每個SG有3個副本。CynosStore還有空閑的副本,可以用來給當前Pool擴容,也可以創建另一個Pool,將這空閑的3個Segment組成一個SG并分配個這個新的Pool。

二、基于日志異步寫的分布式存儲

傳統的數據通常采用WAL(日志先寫)來實現事務和故障恢復。這樣做最直觀的好處是1)數據庫down機后可以根據持久化的WAL來恢復數據頁。2)先寫日志,而不是直接寫數據,可以在數據庫寫操作的關鍵路徑上將隨機IO(寫數據頁)變成順序IO(寫日志),便于提升數據庫性能。

1620基于日志的存儲

圖三 基于日志的存儲

圖三(左)極度抽象地描述了傳統數據庫寫數據的過程:每次修改數據的時候,必須保證日志先持久化之后才可以對數據頁進行持久化。觸發日志持久化的時機通常有

1)事務提交時,這個事務產生的最大日志點之前的所有日志必須持久化之后才能返回給客戶端事務提交成功;

2)當日志緩存空間不夠用時,必須持久化之后才能釋放日志緩存空間;

3)當數據頁緩存空間不夠用時,必須淘汰部分數據頁來釋放緩存空間。比如根據淘汰算法必須要淘汰臟頁A,那么最后修改A的日志點之前的所有日志必須先持久化,然后才可以持久化A到存儲,最后才能真正從數據緩存空間中將A淘汰。

從理論上來說,數據庫只需要持久化日志就可以了。因為只要擁有從數據庫初始化時刻到當前的所有日志,數據庫就能恢復出當前任何一個數據頁的內容。也就是說,數據庫只需要寫日志,而不需要寫數據頁,就能保證數據的完整性和正確性。但是,實際上數據庫實現者不會這么做,因為1)從頭到尾遍歷日志恢復出每個數據頁將是非常耗時的;2)全量日志比數據本身規模要大得多,需要更多的磁盤空間去存儲。

那么,如果持久化日志的存儲設備不僅僅具有存儲能力,還擁有計算能力,能夠自行將日志重放到最新的頁的話,將會怎么樣?是的,如果這樣的話,數據庫引擎就沒有必要將數據頁傳遞給存儲了,因為存儲可以自行計算出新頁并持久化。這就是CynosDB“采用基于日志的存儲”的核心思想。圖三(右)極度抽象地描述了這種思想。圖中計算節點和存儲節點置于不同的物理機,存儲節點除了持久化日志以外,還具備通過apply日志生成最新數據頁面的能力。如此一來,計算節點只需要寫日志到存儲節點即可,而不需要再將數據頁傳遞給存儲節點。

下圖描述了采用基于日志存儲的CynosStore的結構。

1620基于日志的存儲

圖四 CynosStore:基于日志的存儲

此圖描述了數據庫引擎如何訪問CynosStore。數據庫引擎通過CynosStore Client來訪問CynosStore。最核心的兩個操作包括1)寫日志;2)讀數據頁。

數據庫引擎將數據庫日志傳遞給CynosStore,CynosStore Client負責將數據庫日志轉換成CynosStore Journal,并且負責將這些并發寫入的Journal進行序列化,最后根據Journal修改的數據頁路由到不同的SG上去,并發送給SG所屬Store Node。另外,CynosStore Client采用異步的方式監聽各個Store Node的日志持久化確認消息,并將歸并之后的最新的持久化日志點告訴數據庫引擎。

當數據庫引擎訪問的數據頁在緩存中不命中時,需要向CynosStore讀取需要的頁(read block)。read block是同步操作。并且,CynosStore支持一定時間范圍的多版本頁讀取。因為各個Store Node在重放日志時的步調不能完全做到一致,總會有先有后,因此需要讀請求發起者提供一致性點來保證數據庫引擎所要求的一致性,或者默認情況下由CynosStore用最新的一致性點(讀點)去讀數據頁。另外,在一寫多讀的場景下,只讀數據庫實例也需要用到CynosStore提供的多版本特性。

CynosStore提供兩個層面的訪問接口:一個是塊設備層面的接口,另一個是基于塊設備的文件系統層面的接口。分別叫做CynosBS和CynosFS,他們都采用這種異步寫日志、同步讀數據的接口形式。那么,CynosDB for PostgreSQL,采用基于日志的存儲,相比一主多從PostgreSQL集群來說,到底能帶來哪些好處?

1)減少網絡流量。首先,只要存算分離就避免不了計算節點向存儲節點發送數據。如果我們還是使用傳統數據庫+網絡硬盤的方式來做存算分離(計算和存儲介質的分離),那么網絡中除了需要傳遞日志以外,還需要傳遞數據,傳遞數據的大小由并發寫入量、數據庫緩存大小、以及checkpoint頻率來決定。以CynosStore作為底座的CynosDB只需要將日志傳遞給CynosStore就可以了,降低網絡流量。

2)更加有利于基于共享存儲的集群的實現:一個數據庫的多個實例(一寫多讀)訪問同一個Pool。基于日志寫的CynosStore能夠保證只要DB主節點(讀寫節點)寫入日志到CynosStore,就能讓從節點(只讀節點)能夠讀到被這部分日志修改過的數據頁最新版本,而不需要等待主節點通過checkpoint等操作將數據頁持久化到存儲才能讓讀節點見到最新數據頁。這樣能夠大大降低主從數據庫實例之間的延時。不然,從節點需要等待主節點將數據頁持久化之后(checkpoint)才能推進讀點。如果這樣,對于主節點來說,checkpoint的間隔太久的話,就會導致主從延時加大,如果checkpoint間隔太小,又會導致主節點寫數據的網絡流量增大。

當然,apply日志之后的新數據頁的持久化,這部分工作總是要做的,不會憑空消失,只是從數據庫引擎下移到了CynosStore。但是正如前文所述,除了降低不必要的網絡流量以外,CynosStore的各個SG是并行來做redo和持久化的。并且一個Pool的SG數量可以按需擴展,SG的宿主Store Node可以動態調度,因此可以用非常靈活和高效的方式來完成這部分工作。

三、CynosStore Journal(CSJ)

CynosStore Journal(CSJ)完成類似數據庫日志的功能,比如PostgreSQL的WAL。CSJ與PostgreSQL WAL不同的地方在于:CSJ擁有自己的日志格式,與數據庫語義解耦合。PostgreSQL WAL只有PostgreSQL引擎可以生成和解析,也就是說,當其他存儲引擎拿到PostgreSQL WAL片段和這部分片段所修改的基礎頁內容,也沒有辦法恢復出最新的頁內容。CSJ致力于定義一種與各種存儲引擎邏輯無關的日志格式,便于建立一個通用的基于日志的分布式存儲系統。CSJ定了5種Journal類型:

1.SetByte:用Journal中的內容覆蓋指定數據頁中、指定偏移位置、指定長度的連續存儲空間。

\2. SetBit:與SetByte類似,不同的是SetBit的最小粒度是Bit,例如PostgreSQL中hitbit信息,可以轉換成SetBit日志。

\3. ClearPage:當新分配Page時,需要將其初始化,此時新分配頁的原始內容并不重要,因此不需要將其從物理設備中讀出來,而僅僅需要用一個全零頁寫入即可,ClearPage就是描述這種修改的日志類型。

\4. DataMove:有一些寫入操作將頁面中一部分的內容移動到另一個地方,DataMove類型的日志用來描述這種操作。比如PostgreSQL在Vacuum過程中對Page進行compact操作,此時用DataMove比用SetByte日志量更小。

\5. UserDefined:數據庫引擎總會有一些操作并不會修改某個具體的頁面內容,但是需要存放在日志中。比如PostgreSQL的最新的事務id(xid)就是存儲在WAL中,便于數據庫故障恢復時知道從那個xid開始分配。這種類型日志跟數據庫引擎語義相關,不需要CynosStore去理解,但是又需要日志將其持久化。UserDefined就是來描述這種日志的。CynosStore針對這種日志只負責持久化和提供查詢接口,apply CSJ時會忽略它。

以上5種類型的Journal是存儲最底層的日志,只要對數據的寫是基于塊/頁的,都可以轉換成這5種日志來描述。當然,也有一些引擎不太適合轉換成這種最底層的日志格式,比如基于LSM的存儲引擎。

CSJ的另一個特點是亂序持久化,因為一個Pool的CSJ會路由到多個SG上,并且采用異步寫入的方式。而每個SG返回的journal ack并不同步,并且相互穿插,因此CynosStore Client還需要將這些ack進行歸并并推進連續CSJ點(VDL)。

1620 CynosStore日志路由和亂序ACK

圖五 CynosStore日志路由和亂序ACK

只要是連續日志根據數據分片路由,就會有日志亂序ack的問題,從而必須對日志ack進行歸并。Aurora有這個機制,CynosDB同樣有。為了便于理解,我們對Journal中的各個關鍵點的命名采用跟Aurora同樣的方式。

這里需要重點描述的是MTR,MTR是CynosStore提供的原子寫單位,CSJ就是由一個MTR緊挨著一個MTR組成的,任意一個日志必須屬于一個MTR,一個MTR中的多條日志很有可能屬于不同的SG。針對PostgreSQL引擎,可以近似理解為:一個XLogRecord對應一個MTR,一個數據庫事務的日志由一個或者多個MTR組成,多個數據庫并發事務的MTR可以相互穿插。但是CynosStore并不理解和感知數據庫引擎的事務邏輯,而只理解MTR。發送給CynosStore的讀請求所提供的讀點必須不能在一個MTR的內部某個日志點。簡而言之,MTR就是CynosStore的事務。

四、故障恢復

當主實例發生故障后,有可能這個主實例上Pool中各個SG持久化的日志點在全局范圍內并不連續,或者說有空洞。而這些空洞所對應的日志內容已經無從得知。比如有3條連續的日志j1, j2, j3分別路由到三個SG上,分別為sg1, sg2, sg3。在發生故障的那一刻,j1和j3已經成功發送到sg1和sg3。但是j2還在CynosStore Client所在機器的網絡緩沖區中,并且隨著主實例故障而丟失。那么當新的主實例啟動后,這個Pool上就會有不連續的日志j1, j3,而j2已經丟失。

當這種故障場景發生后,新啟動的主實例將會根據上次持久化的連續日志VDL,在每個SG上查詢自從這個VDL之后的所有日志,并將這些日志進行歸并,計算出新的連續持久化的日志號VDL。這就是新的一致性點。新實例通過CynosStore提供的Truncate接口將每個SG上大于VDL的日志truncate掉,那么新實例產生的第一條journal將從這個新的VDL的下一條開始。

1620故障恢復時日志恢復過程

圖六:故障恢復時日志恢復過程

如果圖五剛好是某個數據庫實例故障發生的時間點,當重新啟動一個數據庫讀寫實例之后,圖六就是計算新的一致性點的過程。CynosStore Client會計算得出新的一致性點就是8,并且把大于8的日志都Truncate掉。也就是把SG2上的9和10truncate掉。下一個產生的日志將會從9開始。

五、多副本一致性

CynosStore采用Multi-RAFT來實現SG的多副本一致性, CynosStore采用批量和異步流水線的方式來提升RAFT的吞吐量。我們采用CynosStore自定義的benchmark測得單個SG上日志持久化的吞吐量為375萬條/每秒。CynosStore benchmark采用異步寫入日志的方式測試CynosStore的吞吐量,日志類型包含SetByte和SetBit兩種,寫日志線程持續不斷地寫入日志,監聽線程負責處理ack回包并推進VDL,然后benchmark測量單位時間內VDL的推進速度。375萬條/秒意味著每秒鐘一個SG持久化375萬條SetByte和SetBit日志。在一個SG的場景下,CynosStore Client到Store Node的平均網絡流量171MB/每秒,這也是一個Leader到一個Follower的網絡流量。

六、一寫多讀

CynosDB基于共享存儲CynosStore,提供對同一個Pool上的一寫多讀數據庫實例的支持,以提升數據庫的吞吐量。基于共享存儲的一寫多讀需要解決兩個問題:

\1. 主節點(讀寫節點)如何將對頁的修改通知給從節點(只讀節點)。因為從節點也是有Buffer的,當從節點緩存的頁面在主節點中被修改時,從節點需要一種機制來得知這個被修改的消息,從而在從節點Buffer中更新這個修改或者從CynosStore中重讀這個頁的新版本。

\2. 從節點上的讀請求如何讀到數據庫的一致性的快照。開源PostgreSQL的主備模式中,備機通過利用主機同步過來的快照信息和事務信息構造一個快照(活動事務列表)。CynosDB的從節點除了需要數據庫快照(活動事務列表)以外,還需要一個CynosStore的快照(一致性讀點)。因為分片的日志時并行apply的。

如果一個一寫多讀的共享存儲數據庫集群的存儲本身不具備日志重做的能力,主從內存頁的同步有兩種備選方案:

第一種備選方案,主從之間只同步日志。從實例將至少需要保留主實例自從上次checkpoint以來所有產生的日志,一旦從實例產生cache miss,只能從存儲上讀取上次checkpoint的base頁,并在此基礎上重放日志緩存中自上次checkpoint以來的所有關于這個頁的修改。這種方法的關鍵問題在于如果主實例checkpoint之間的時間間隔太長,或者日志量太大,會導致從實例在命中率不高的情況下在apply日志上耗費非常多的時間。甚至,極端場景下,導致從實例對同一個頁會反復多次apply同一段日志,除了大幅增大查詢時延,還產生了很多沒必要的CPU開銷,同時也會導致主從之間的延時有可能大幅增加。

第二種備選方案,主實例向從實例提供讀取內存緩沖區數據頁的服務,主實例定期將被修改的頁號和日志同步給從實例。當讀頁時,從實例首先根據主實例同步的被修改的頁號信息來判斷是1)直接使用從實例自己的內存頁,還是2)根據內存頁和日志重放新的內存頁,還是3)從主實例拉取最新的內存頁,還是4)從存儲讀取頁。這種方法有點類似Oracle RAC的簡化版。這種方案要解決兩個關鍵問題:1)不同的從實例從主實例獲取的頁可能是不同版本,主實例內存頁服務有可能需要提供多版本的能力。2)讀內存頁服務可能對主實例產生較大負擔,因為除了多個從實例的影響以外,還有一點就是每次主實例中的某個頁哪怕修改很小的一部分內容,從實例如果讀到此頁則必須拉取整頁內容。大致來說,主實例修改越頻繁,從實例拉取也會更頻繁。

相比較來說,CynosStore也需要同步臟頁,但是CynosStore的從實例獲取新頁的方式要靈活的多有兩種選擇1)從日志重放內存頁;2)從StoreNode讀取。從實例對同步臟頁需要的最小信息僅僅是到底哪些頁被主實例給修改過,主從同步日志內容是為了讓從實例加速,以及降低Store Node的負擔。

1620CynosDB一寫多讀

圖七 CynosDB一寫多讀

圖七描述了一寫一讀(一主一從)的基本框架,一寫多讀(一主多從)就是一寫一讀的疊加。CynosStore Client(CSClient)運行態區分主從,主CSClient源源不斷地將CynosStore Journal(CSJ)從主實例發送到從實例,與開源PostgreSQL主備模式不同的是,只要這些連續的日志到達從實例,不用等到這些日志全部apply,DB engine就可以讀到這些日志所修改的最新版本。從而降低主從之間的時延。這里體現“基于日志的存儲”的優勢:只要主實例將日志持久化到Store Node,從實例即可讀到這些日志所修改的最新版本數據頁。

七、結語

CynosStore是一個完全從零打造、適應云數據庫的分布式存儲。CynosStore在架構上具備一些天然優勢:1)存儲計算分離,并且把存儲計算的網絡流量降到最低; 2)提升資源利用率,降低云成本,3)更加有利于數據庫實例實現一寫多讀,4)相比一主兩從的傳統RDS集群具備更高的性能。除此之外,后續我們會在性能、高可用、資源隔離等方面對CynosStore進行進一步的增強。

此文已由作者授權騰訊云+社區發布

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

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

相關文章

Hive高級函數

Hive的函數太多了。用法和sql的差不多。 簡單查詢 select ... from...where... 使用各種函數 hive>show functions;//查看所有函數 hive>describe function explode;//查看函數的使用方法 LIMIT語句 列別名 嵌套select語句 標準函數: reverse() upper() ...…

groupby索引有效嗎_SQL IN 一定走索引嗎?

摘要IN 一定走索引嗎?那當然了,不走索引還能全部掃描嗎?好像之前有看到過什么Exist,IN走不走索引的討論。但是好像看的太久了,又忘記了。哈哈,如果你也忘記了MySQL中IN是如何查詢的,就來復習下吧。問題問題…

mysql函數使用場景_mysql的函數和存儲過程的比較,以及在實際場景中的使用案例...

一.存儲過程和函數的區別函數調用有返回值存儲過程調用用call語句,函數調用直接飲用函數名參數IN,OUT,INOUT只適用于存儲過程,對函數而言所有參數默認都是輸入參數IN用于把數值傳入到存儲過程中OUT用于輸出參數將數值傳遞給調用者…

hive性能調優

原文:http://www.tuicool.com/articles/rMvQvm ---------------------------------------------------------------------- limit 限制調整 -- 因為使用 limit 語句時候,是先執行整個查詢語句,然后再返回部分結果的 set hive.limit.optimize…

推薦系統之 BPR 算法及 Librec的BPR算法實現【1】

【推薦系統之 BPR 算法】 1、關于BPR的論文原文: BPR: Bayesian Personalized Ranking from Implicit Feedback 2、參考1:論文快讀 - BPR: Bayesian Personalized Ranking from Implicit Feedback (該博主的網站不錯,尤其論文快…

ios 篩選_萬千網友讓quot;低調使用quot;的軟件!居然還支持iOS

點擊藍字關注我們昨天的耳朵神器大家感覺怎么樣?享受了耳朵今天我們享受一下眼睛~可能很多同學對漫畫是情有獨鐘但是,之前小黑一直介紹的都是安卓端的軟件今天要給大家介紹的這款軟件是IOS安卓都有終于可以不被IOS的同學吐槽了而且經過測試小黑真的想說一…

Linux卸載/刪除多余網卡

卸載 使用命令ifconfig命令查看網卡情況 確認自己使用的是哪一塊網卡,然后把其它的網卡都卸載掉。 運行命令ifconfig 網卡名稱 down。 如: ifconfig eth1 down 再次運行ifconfig就會發現被卸載掉的網卡沒了。現在可以ping 一下內網的IP試試看能不能pin…

CentOS7:JDK1.7.0_80安裝

一、安裝前檢查 執行以下命令: rpm -qa | grep jdk 查看系統是否已經自帶openjdk,如果存在 執行以下命令: yum -y remove files files為查出的、系統自帶的openjdk相關文件,運行以上命令將相關文件卸載 執行命令 java -version[rootlocalhost…

python海龜繪圖畫圣誕帽男人_python海龜繪圖實例教程

本文以實例形式介紹了python turtle模塊即海龜繪圖的使用方法,對于需要進行圖形編程的朋友相信會有一定的借鑒價值。python turtle模塊簡介:python2.6版本中引入的一個簡單的繪圖工具,叫做海龜繪圖(turtle graphics)1.使用海龜繪圖首先我們需…

spring+mybatis 多數據源整合

原文&#xff1a;http://blog.csdn.net/fhx007/article/details/12530735 ---------------------------------------------------------------------------------- 直接看spring的配置吧 <!-- 數據源配置 --> <bean id"ds1" class"org.apache.commo…

四管前級怎么去掉高低音音調_一些歌曲音調太高怎么才能唱上去??

展開全部首先得提高肺活量 然后就是練聲&#xff01;怎 樣 練 聲&#xff1a;練聲的目的1&#xff0c;使歌唱發聲系統各器官的肌肉更e68a84e8a2ad62616964757a686964616f31333236373231有力&#xff0c;并能協調一致。2&#xff0c;建立正確的聲音概念。3&#xff0c;擴展音域&…

python繪制星空_用python畫星空源代碼是什么?

用python畫星空源代碼是什么&#xff1f;用python畫星空源代碼是from turtle import *from random import random,randintscreen Screen()width ,height 800,600screen.setup(width,height)screen.title("模擬3D星空")screen.bgcolor("black")screen.mod…

Linux - xshell上傳文件報錯亂碼

xshell上傳文件報錯亂碼&#xff0c;解決方法 rz -be 回車 下載sz filename轉載于:https://www.cnblogs.com/RzCong/p/8600899.html

java元數據是什么_用存儲過程和 JAVA 寫報表數據源有什么弊端?

用存儲過程和 JAVA 寫報表數據源有什么弊端&#xff1f;跟著小編一起來一看一下吧&#xff01;我們在報表開發中經常會使用存儲過程準備數據&#xff0c;存儲過程支持分步計算&#xff0c;可以實現非常復雜的計算邏輯&#xff0c;為報表開發帶來便利。所以&#xff0c;報表開發…

mysql多實例安裝啟動_MySQL多實例安裝啟動

Tips&#xff1a;之前我們的一個實例是mysql3306&#xff0c;我們現在再安裝一個mysql33071。和之前一樣&#xff0c;創建需要的目錄文件夾mkdir -p /data/mysql/mysql3307/{data,logs,tmp}創建完 就給文件授權chown -R mysql:mysql /data/mysql/mysql3307/2.進入mysql3307cd /…

用vhdl實現4位加減法計數器_32位加減法器設計

功能特性設計思路基于一位全加器&#xff0c;設計32位并行加法器。并行加法器中全加器的位數與操作數相同&#xff0c;影響速度&#xff08;延時&#xff09;的主要因素是進位信號的傳遞。主要的高速加法器【1】有基本上都是在超前進位加法器&#xff08;CLA&#xff09;的基礎…

用vim + xdebug 來追蹤thinkphp的執行過程

tree命令的使用幾個有實際應用的參數 -a 這是默認的 -d: 只顯式目錄, 不需要顯式目錄下的文件 -L: 列出顯式的深度. 當前目錄下的所有東西為第一級...在tp下, 有多個Common但是它們的含義不同:Application|- Common (前后臺都使用的公共文件所在目錄)|- Common (公共函數目錄)…

mybatis 中#與$的區別

MyBatis/Ibatis中#和$的區別 #{} 解析的是占位符&#xff1f;可以防止SQL注入&#xff0c;比如打印出來的語句 select * from table where id? 然而${} 則是不能防止SQL注入打印出來的語句 select * from table where id2 實實在在的參數

綠色背景配什么顏色文字_灰色褲子配什么顏色上衣好看

我們許多人都喜歡灰色。灰色是一種很酷的自然色。灰色大氣而沉穩。它介于黑白之間&#xff0c;是一種多用途的顏色&#xff0c;與其他顏色搭配將變得時尚而優雅。那么秋冬季節灰色褲子配什么顏色的上衣好看呢&#xff1f;接下來就來看一組時尚大人的灰色褲子穿搭吧。look1 保溫…

浮柵場效應管 符號_場效應管主要參數與特點,場效應管與其他管子的對比

場效應晶體管(Field Effect Transistor縮寫(FET))簡稱場效應管。主要有兩種類型&#xff1a;結型場效應管(junction FET—JFET)和金屬-氧化物半導體場效應管(metal-oxide semiconductor FET&#xff0c;簡稱MOS-FET)。場效應管由多數載流子參與導電&#xff0c;也稱為單極型晶體…