我使用this API從中檢索了大約24000個項目。從API中檢索數據的最快方法
所以首先我從here(警告,緩慢的瀏覽器可能會崩潰)採取項目列表。
然後我遍歷所有項目,並找到每個項目的所有信息。喜歡的東西:
https://api.guildwars2.com/v2/items/itemidhere
和刀片的信息到MySQL數據庫。
PD:真正的問題出現在下面的這一行之後。
我試圖找到最快的方式從這些鏈接獲取信息並插入它。對於這個我使用:
-GSON庫
-HikariCP(數據庫連接池)
-threads(最簡單快捷的控制方式JSON)(每個線程需要的1000個項目護理,如果有24個線程)
我做了一些測試,這裏是收集和插入24.000項目的結果:
-threads:50
-DB游泳池大小:10
- 時間:644秒
-threads:100
-DB池尺寸:10
-Time:607秒
-threads:250
-DB池尺寸:15
-Time:662秒
- 主題:500
-DB游泳池大小:20
- 時間:689秒
我知道這裏最慢的就是網絡。
我的電腦和互聯網的arent慢:
-300mb/s的網絡
-Intel 5820k
-16GB DDR4
所以留下什麼可能是代碼實現...
HikariConfig config = new HikariConfig();
config.setDriverClassName("com.mysql.jdbc.Driver");
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("root");
config.setPassword("none");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
config.setMaximumPoolSize(depending on case);
Core.ds = new HikariDataSource(config);
這是數據庫連接池的設置。通過所有的列表
final CyclicBarrier _threadGate = new CyclicBarrier(depends on case);
ArrayList<Thread> _threadList = new ArrayList<>();
然後
_threadList.add(new Thread() {
@Override
public void run() {
try {
_threadGate.await();
//Parsing happens a bit later
我在這裏循環,並從URL中的信息(我跳過變量聲明):我先說一個循環屏障的線程
_id = _itemList.get(i);
_stringUrl = "https://api.guildwars2.com/v2/items/" + _id;
_responseText = new URL(_stringUrl);
_requestUrl = (HttpURLConnection) _responseText.openConnection();
_requestUrl.connect();
_requestStatus = _requestUrl.getResponseCode();
if(_requestStatus == 200){
_jsonParser = new JsonParser();
_rootElement = _jsonParser.parse(new InputStreamReader((InputStream) _requestUrl.getContent(), "UTF-8"));
_rootObject = _rootElement.getAsJsonObject();
而從做了很多解析和檢查,如果json退出等等等等......並在最後插入...
這裏是我開始線程一切都在主類處理後:
for (int i = 0; i < _threadList.size(); i++) {
_threadList.get(i).start();
}
信息:here約你爲什麼不我用更大的池大小。
什麼,我不明白的是:
- 爲什麼,如果有多個線程的結果是慢
-I平均,CMON也許網絡速度慢,但是,很少有人要求可以填補300MB/s的?
- 是否會實現更好的代碼使其更快?
我真正看到它像這樣:
- 更多線程 - >互聯網速度較慢,這使得拉動信息慢。
-bigger池大小 - >慢插入由於許多連接
- 更多線程和小連接池 - >插入排隊並停止
-few線程和小連接池 - >慢拉信息
更新
- 通過彙集,1個連接/池進行經典連接,結果比較慢,比如慢30秒
- 通過CyclicBarrier執行ExecutorService,結果減慢10秒。
當你完成它們後,你是否關閉了連接?你是一次一件或一批地保管這些物品嗎?批量將是更快的方式來插入它們 – rj93
更多的線程=更多Taskswitches。所以有一個「Peek」,更多的線程使它變得更糟。有人建議,作爲一條經驗法則,不要爲一個並行任務使用比CPU內核多的線程。我個人不知道這是否合理。另外我會推薦一個ExecutorService而不是ArrayList –
Fildor
@Fildor試着用ExecutorService executor = Executors.newFixedThreadPool(some pools);但仍然是相同的結果,實際上它可能會減慢5-10秒 – Alpha2k