乾貨 | Spark SQL 中繼資料雙主高可用方案揭秘,spark中繼資料
點擊上方“中興開發人員社區”,關注我們
每天讀一篇一線開發人員原創好文
來源 | 中興大資料
“
開源的Spark SQL並不支援高可用,但實際應用中高可用對於使用者意義重大。中興大資料平台DAP在對應的ZDH中實現了Spark SQL的高可用。
”
Spark SQL的高可用,是兩個Spark SQL服務上線的時候向SQL進行註冊,使用者串連的JDBC URL指定為Zookeeper的列表,串連的時候會通過Zookeeper叢集擷取Spark SQL節點資訊,然後串連到Spark SQL服務節點。
Spark SQL中繼資料雙主主要是用MySQL實現,MySQL支援單向、非同步複製,複製過程中一個伺服器充當主伺服器,而一個或多個其它伺服器充當從伺服器。主伺服器將更新寫入二進位記錄檔,並維護記錄檔的索引以追蹤記錄檔迴圈。從伺服器接收從那時起發生的任何更新,然後封鎖並等待主伺服器通知下一次更新。
在實際項目中,兩台分佈於異地的主機上安裝有MySQL資料庫,兩台伺服器互為主備,當其中一台機器出現故障時,另外一台能夠接管伺服器上的應用,這就需要兩台資料庫的資料要即時保持一致,在這裡使用MySQL的同步功能實現雙機的同步複製。
實現方案
目前SparkSQL節點訪問雙主的中繼資料庫主要考慮兩種方案:
中SparkSQL節點分別串連單個MySQL節點,不同SparkSQL節點對中繼資料庫的更改會在MySQL節點之間進行同步。
中SparkSQL節點分別串連多個MetaStore節點,每個MetaStore節點串連對應的MySQL節點,不同SparkSQL節點對中繼資料庫的更改會在MySQL節點之間進行同步。
上面兩種SparkSQL節點訪問雙主的中繼資料庫方案下,用戶端擷取SparkSQL服務的方式是相同的,主要通過如下方式:
Beeline串連
程式通過JDBC連接埠訪問
Beeline方式首先通過Zookeeper叢集擷取SparkSQL節點資訊,然後串連到SparkSQL服務節點。當串連的SparkSQL節點異常時,可以通過重試幾次擷取SparkSQL服務。
程式通過JDBC連接埠串連到對應的SparkSQL節點的方式下,如果正在串連的SparkSQL節點出現異常,可以通過在代碼中進行異常捕獲的方式重新擷取SparkSQL服務。
下面主要對兩種方案的功能可行性以及異常情況進行驗證。
測試環境
MySQL:10.43.183.121和10.43.183.122兩台主機
SparkSQL: 10.43.183.121和10.43.183.122兩台主機
Hive MetaStoreServer: 10.43.183.121和10.43.183.122兩台主機
測試情境
- 情境一:SparkSQL節點直接連接MySQL高可用驗證
每個SparkSQL節點直接連接一個MySQL節點。驗證中繼資料能否成功同步以及MySQL節點失效能否自動切換。
測試步驟如下:
1. 修改配置
SparkSQL配置修改如下:
10.43.183.121對應的JDBC串連配置為10.43.183.121上的MySQL
10.43.183.122對應的JDBC串連配置為10.43.183.122上的MySQL
2. Beeline串連10.43.183.121節點的SparkSQL。
3. 建立表test,分別尋找兩個MySQL的hiveomm資料庫的tbls表,可以看到test記錄。表明中繼資料同步成功。
4. 將SparkSQL當前串連的MySQL停掉。
5. Beeline 介面執行“show tables”命令,查詢異常。
6. 斷開Beeline串連並多次重新串連10.43.183.121節點的SparkSQL,串連異常。
7. 用SQL URL串連SparkSQL服務!connectjdbc:hive2://10.43.183.121:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=sparkThriftServer重試若干次可以串連上SparkSQL服務,通過“show tables”命令可以查到test表。
8. 啟動MySQL節點,Beeline重新串連10.43.183.121節點,可以串連到SparkSQL節點。執行“show tables”命令,可以查詢到test表資訊。
測試結論:
MySQL之間的中繼資料可以同步。
MySQL節點掛掉會導致Beeline無法查詢。
Beeline重新串連無法串連到對應的SparkSQL節點。
Beeline通過SQL URL串連SparkSQL服務,可以在嘗試一定次數之後串連到可用的SparkSQL節點。
MetaStoreServer節點主要用於MySQL節點失效時的容錯,每個MetaStoreServer節點對應一個MySQL節點,每個SparkSQL節點配置多個MetaStoreServer節點。驗證中繼資料能否成功同步以及MySQL節點失效能否自動切換。
測試步驟如下:
1. 修改配置
MetaStoreServer節點配置修改如下:
10.43.183.121節點的MetaStoreServer配置10.43.183.121節點上的MySQL
10.43.183.122節點的MetaStoreServer配置10.43.183.122節點上的MySQL
SparkSQL添加對應配置:
2. Beeline串連10.43.183.121節點的SparkSQL。
3. 建立表test,分別尋找兩個MySQL的hiveomm資料庫的tbls表,可以看到test記錄,表明中繼資料同步成功。
4. 將SparkSQL當前串連的MetaStoreServer(通過日誌看到)對應的MySQL停掉。
5. Beeline 介面執行“show tables”命令,查詢異常。
6. 斷開Beeline串連並多次重新串連10.43.183.121節點的SparkSQL,串連出現異常。
7. 用SQL url串連SparkSQL服務!connectjdbc:hive2://10.43.183.121:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=sparkThriftServer始終無法串連上SparkSQL服務,通過“show tables”命令可以查到test表。
8. 重新啟動MySQL節點,Beeline重新串連10.43.183.121節點,可以串連到SparkSQL節點。執行“show tables”命令,可以查詢到test表資訊。
測試結論:
MySQL之間的中繼資料可以同步。
MySQL節點掛掉會導致Beeline無法查詢。
MySQL節點掛掉的情況下,Beeline重新串連SparkSQL節點,無法串連到對應的SparkSQL節點。
MySQL節點掛掉的情況下,Beeline通過SQL URL串連SparkSQL服務無法串連到對應的SparkSQL服務。
服務配置同情境一中的方式,通過JDBC串連到SparkSQL節點,範例程式碼如下:
public static void main(String[] args)
{
int num = 0;
Connection conn = null;
ResultSet rs = null;
PreparedStatement pstat = null;
while (num < 3)
{
num = num + 1;
try
{
Class.forName("org.apache.hive.jdbc.HiveDriver");
if (conn == null)
{
if (args.length > 0)
conn = DriverManager.getConnection(args[0], "mr", "mr");
else
conn = DriverManager
.getConnection("jdbc:hive2://10.43.183.121:18000", "mr", "mr");
}
pstat = conn.prepareStatement("select * from test");
rs = pstat.executeQuery();
while (rs.next())
{
System.out.println(rs.getString("name"));
}
break;
} catch (Exception e)
{
e.printStackTrace();
try
{
conn = DriverManager
.getConnection("jdbc:hive2://10.43.183.122:18000", "mr", "mr");
} catch (SQLException e1)
{
e1.printStackTrace();
}
} finally
{
try
{
rs.close();
pstat.close();
conn.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
測試結論:
通過JDBC串連到SparkSQL節點可以通過異常捕獲的方式實現實現MySQL節點故障之後擷取SparkSQL服務。
測試結論
SparkSQL訪問中繼資料服務的兩種方案都可以正常訪問中繼資料庫並且實現中繼資料庫的同步,而且中繼資料庫異常的情況下,兩種方案的處理是一樣的。
但是SparkSQL串連MetaStore節點需要串連到Hive的MetaStore節點,對比直接連接MySQL會有多餘的MetaStore進程需要維護、更加複雜的中繼資料庫管理方式以及版本問題。
因此,建議用MySQL雙主的方式實現SparkSQL的雙主高可用,不同的SparkSQL節點直接連接到不同的MySQL。
訪問SparkSQL服務的方式可以採用兩種方式:
Beeline串連SQL URL的方式,對於MySQL異常的情況,可以重新串連繼續擷取SparkSQL服務。
調用JDBC介面訪問SparkSQL,捕獲異常並對異常情況作處理,重新串連到其他SparkSQL節點。
配置方式
SparkSQL節點直接連接MySQL的配置如下:
在服務配置介面將javax.jdo.option.ConnectionURL項配置任一MySQL節點作為預設MySQL節點,如所示:
SparkSQL節點可以在自訂HIVE_SITE_CUSTOM_CONFIG中配置其他MySQL節點作為其對應的MySQL節點,配置格式為:
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>${{mysql_url}}</value>
</property>
${{mysql_url}}為MySQL服務的URL。
如所示: