礦池負載運行監測記錄

從2019年2月開始開發礦池程序時,從礦池開發的一個陌生人,從不懂到學習,到實踐,本文沒有辦法記錄全部細節,只將在實踐過程當中遇到的重點問題記錄一下,供後續人士參考。html

因爲從事礦業軟件開發的人,在全球都不多,從事礦池開發的就更少了,找不到能夠參考的完整例子及各類問題的解答,因爲遇到的問題又與各幣種、算法、各廠家礦機等多因素相關,致使排查問題時,特別難以鎖定。 算法

 

     在網上搜索後,被普遍使用的礦池程序有mpos,nomp,unomp,CoiniumServ,以及基於nomp的各類變種礦池。咱們在對比了 CoiniumServ以及unomp後,選擇基於unomp作基礎,改造開發。數據庫

 

性能問題:unomp 對nomp 改造主要是基於nomp使用MySql 後,MySql成爲了整個系統的性能瓶頸。緩存

咱們在第一個版本開發時,也使用了基於 MySql(也兼容其它關係型數據庫)作數據持久化存儲,發如今 4000臺機器時,MySql 已嚴重拖累了整個系統的效能,好在MySql雖然性能差,但並未出現過死機等狀況,可靠性仍是很高的。基於此,若是多礦池,每一個礦池幾萬臺礦機的量,MySql是扛不住了。所以,考慮更換持久化存儲。能過性能測試,選擇了MongoDB,它有超過10-100倍的性能提高,仍是在未作性能優化的前提下的測試結果。 性能優化

      通過一週左右的時間,將數據存儲更換爲MongoDB, 目標選定爲3萬臺礦機,在一臺24核,16G的服務器上,能夠穩定運行48-72小時,時有宕機,緣由未明。服務器

      又是莫名的問題,排查陷入無頭緒的各類嘗試。首先,下降 CPU使用率,經過優化MongoDB,CPU使用率降到了 平均40%左右,最高90%,硬件在這個水平是恰好,知足需求。但宕機的問題,在48-72小時時,仍然發生,所以能夠確信,問題沒有獲得根本解決。運維

     

查看分析日誌,錯誤有: ide

IBeam.Cache.Redis.RedisProvider [(null)] - InternalPut Key=hzUih+jvf6Jbrj7hhUjlhVP/sP4=,Error=System.OutOfMemoryException: 引起類型爲「System.OutOfMemoryException」的異常。
   在 System.IO.MemoryStream.set_Capacity(Int32 value)
   在 System.IO.MemoryStream.EnsureCapacity(Int32 value)
   在 System.IO.MemoryStream.WriteByte(Byte value)

       這個異常提示,Redis內存耗盡, 爲何爲這樣?緣由爲緩存已達到Redis的內存使用上限,解決辦法爲:設置當Redis達到內存上限時,設置淘汰策略。這樣可使已分配的內存置換出來。     性能

      Redis 持久化存儲時,若是數據量很大,好比10G以上,而服務器的內存又只有16G,此時將致使Redis轉儲失敗,中止服務。解決辦法:將Redis可使用的最大內存設置爲 系統內存的一半如下。此時Redis 在Fork一個進程轉儲時能夠正常進行。學習

      另外,當Redis達到最大內存時,設置其不能中止服務。 

     

    如下錯誤至今沒法解決: 

 2019-03-25 05:33:24,485 [79] ERROR IBeam.Cache.Redis.RedisProvider [(null)] - GetRedis Host=127.0.0.1,Port=6379,Error=System.InvalidOperationException: No servers are connected or configured. 在 CacheManager.Core.BaseCacheManager`1..ctor(String name, ICacheManagerConfiguration configuration) 在 CacheManager.Core.BaseCacheManager`1..ctor(ICacheManagerConfiguration configuration) 在 CacheManager.Core.CacheFactory.Build[TCacheValue](String cacheName, Action`1 settings) 在 IBeam.Cache.Redis.RedisProvider.GetRedis(String host, Int32 port, Int32 database, String password)

 

2019-03-25 05:33:24,485 [79] ERROR System.RuntimeType [(null)] - TryTimesDo TryTimes=2, ActionHandler=System.Object CGet(System.String),Val1=CPpI4tlMoULGbhXAx+FAg7nXox4=,Error=StackExchange.Redis.RedisConnectionException: No connection is available to service this operation: EVAL; SocketFailure on 127.0.0.1:6379/Interactive, origin: CheckForStaleConnection, input-buffer: 0, outstanding: 62, last-read: 1s ago, last-write: 1s ago, unanswered-write: 1s ago, keep-alive: 60s, pending: 0, state: ConnectedEstablished, in: 0, ar: 0, last-heartbeat: 1s ago, last-mbeat: 0s ago, global: 0s ago, mgr: RecordConnectionFailed_ReportFailure, err: never; IOCP: (Busy=0,Free=1000,Min=16,Max=1000), WORKER: (Busy=98,Free=925,Min=16,Max=1023), Local-CPU: n/a ---> StackExchange.Redis.RedisConnectionException: SocketFailure on 127.0.0.1:6379/Interactive, origin: CheckForStaleConnection, input-buffer: 0, outstanding: 62, last-read: 1s ago, last-write: 1s ago, unanswered-write: 1s ago, keep-alive: 60s, pending: 0, state: ConnectedEstablished, in: 0, ar: 0, last-heartbeat: 1s ago, last-mbeat: 0s ago, global: 0s ago, mgr: RecordConnectionFailed_ReportFailure, err: never --- 內部異常堆棧跟蹤的結尾 --- 在 IBeam.Cache.Redis.RedisProvider.InternalGet(String cacheKey) 在 IBeam.Cache.Redis.RedisProvider.CGet(String cacheKey) 在 IBeam.MDAA.ActionHelper.TryTimesDo[T1,TResult](MAction`2 actionHandler, T1 val1, Int32 tryTimes) 

 

表現出的現象爲:Redis沒有可用鏈接,重啓Redis服務,故障排除,但問題是不知道Redis何時出故障,運維難度高。目前爲了排除這個故障,將Redis部署爲集羣節點,由Redis節點保證服務的高可用。可能存在Socket端口耗盡的問題,因爲沒有時間去排查,直接將Redis服務移到Linux平臺上,由專門的機器運行,或直接使用雲平臺的 集羣節點。

 另外,MongoDB在運行的近一個月時間中,前期運行一直都正常,但後面幾天,伴隨Redis宕機時,MongoDB也宕機,爲了保證高可用及可靠性,建議仍是單獨移出來單獨部署或使用分片+複本集。

 

 根據以上經驗分開部署後的單機節點運行狀況以下:

Redis服務器(8核16G):

 

能夠看出,在3000臺負載中,整個8核的使用率很低,能夠將此節點降爲 1核16G便可,咱們在實際使用中,Redis只是做爲緩存使用,不開啓持久化存儲

 

Web及適配器服務器(4核4G):

在實際cpu負載監測下,CPU在計算期間的峯值達到了 40%,知足使用。

 

MongoDB服務器(4核8G):

從實際的運行中能夠看出,一開始10000臺礦機負載時,CPU佔用爲100%,能夠運算出正常的結果,但建了索引優化後的負載爲30000臺,cpu佔用只有7%左右,可見運行優化的重要性。

 

如下爲Redis配置要點,生產環境中不能使用默認配置:

  • 是否轉存在硬盤?轉存時間間隔。
  • Redis可使用的最大內存是多少?
  • 當Redis出現故障時是否中止服務?
  • 當Redis達到最大內存閥值時的淘汰策略是什麼?
  • 若是須要轉存(持久化),存儲的方式是什麼?

全部這些都影響Redis的可靠性和可用性,Linux中Redis的配置文件所在目錄爲:

/etc/Redis/Redis.conf

 

另外,配置完成後,檢查綁定IP地址,檢查端口號,檢查ufw防火牆設置

集羣配置參考連接:

http://www.javashuo.com/article/p-ozppdxgj-kg.html

http://www.javashuo.com/article/p-mxdparyf-gg.html

相關文章
相關標籤/搜索