Uber如何使用go語言創建高效的查詢服務

在2015年初我們創建了一個微服務,它只做一件事(也確實做得很好)就是地理圍欄查詢。一年后它成了Uber高頻查詢(QPS)服務,本次要講的故事就是我們為什么創建這個服務,以及編程語言新秀Go如何幫我們快速創建和擴展該服務。

?

背景

在Uber,一個地理圍欄就是在地表人為定義的地理區域(或多邊形幾何區域)。地理圍欄在Uber被廣泛用于基于地理位置的設置。向用戶展示給定區域有哪些產品可以使用,根據特殊需要(如機場)定義區域,并在乘車高峰時在相鄰區域實施動態定價是我們產品的重要應用場景。


Uber,高速查詢,服務

一個科羅拉多地理圍欄示例。

?

第一步是通過用戶手機獲取地理位置信息如經緯度,進而確定用戶所在地理圍欄。這個功能分散在多個服務或模塊中。因為我們從整體架構向微服務架構遷移,我們選擇將這個功能做成一個新的微服務。

?

?使用Go語言

Node.js曾經是我們實時市場團隊主力開發語言,所以我們在Node.js上有較多的知識儲備和經驗。但是Go在以下幾個方面更符合我們的需求:

?

1、高吞吐低延遲的需要。Uber手機應用中的每個請求都需要地理圍欄查詢,而且響應快速(99% < 100毫秒)頻繁(每秒成千上萬),
2、適用于CPU密集型。地理圍欄查詢是點聚計算的CPU密集型服務。Node.js非常適合我們其他I/O密集型應用,但由于Node天生就是解釋型動態語言,所以它不適合此類應用。
3、非中斷后臺加載。為了給查詢服務提供最新的地理圍欄數據,服務需要在后臺不斷的從多個數據源加載內存數據。因為Node.js是單線程的,所以后臺更新會對CPU造成較長時候的堵塞(例如,CPU密集的JSON解析),從而影響到查詢響應時長。但Go不存在這些問題,因為goroutines 可以使用多核,后臺任務和前臺查詢可以并行。


是否使用地理信息索引:這是一個問題

?

通過經緯度指定一個地理位置后,如果從我們成千上萬的地理圍欄中確定它屬于哪一個?簡單粗暴的做法是:使用點聚檢查方式,如光線投射算法,從所有地理圍欄數據中查找。但這種式太慢。所以,我們如何縮小查詢范圍以提高效率?

?

我們沒有使用R-tree做地理圍欄索引和比較復雜的S2,通過觀察我們發現Uber的業務模式是以城市為中心的;業務規則和地理圍欄通常用一個城市來定義,所以我們選擇了一個簡單的路由方式。我們把地理圍欄整理為兩層結構,第一層是城市地理圍欄(定義城市邊界),第二層是每個城市內的地理圍欄。

?

?對于每個查詢,我們首先對所有城市地理圍欄做線性掃描查找所在城市,然后對該城市的地理圍欄數據做線性掃描。這個解析方案的運算復雜度是O(N),? 通過這個簡單的技術我們將N從10,000s減少到100s。

?

架構

我們希望這個服務是無狀態的,這樣每個請求可以發送到任意實例,而且得到結果是一致的。這意味著每個實例都擁有全量數據,而不是只存儲部分數據。我們生成了一個統一的拉取計劃,這樣不同服務實際的地理圍欄數據可以保持同步。因面這個服務的架構也就變得簡單。后臺任務定時從不同的數據存儲拉取地理圍欄數據。這些數據是在內存中存儲,以提高查詢速度,當服務需要重啟時會序列化到本地文件。


Uber,高速查詢,服務

我們的地理圍欄數據查詢架構


處理Go內存模型

在我們的架構中需要對內存中的地理索引數據并發讀寫。當后臺拉取任務寫索引時,可能前臺查詢引擎同步讀取索引。有Node.js經驗的人熟悉了單線程模式,Go的內存模型對他們是一個挑戰。這對我們曾產生對負面影響。我們試圖使用sync/atomic 包的原語StorePointer/LoadPointer 來管理內存邊界問題,但這導致代碼很脆弱且難以維護。

?

?最后,我們采取了折中的方式,使用讀寫鎖來異步處理對地理索引的訪問。為了減少鎖的爭奪,新的索引在以原子的方式合并到主索引之前先建立索引片段。與 StorePointer/LoadPointer的方式相比,這些稍微增加一些延遲,但我們有理由相信代碼的簡潔和可維護性比這一點小小的延遲更有價值。

?

我們的經驗

回顧以往,我們很慶幸當初使用Go語言,并使用這種新的語言開發我們的服務。亮點如下:

?

1、開發效率高。C++,Java和Node.js的開發者只需要很短的時間就可以掌握Go,代碼易于維護。(靜態語言更加清晰,沒有莫名其妙的意外)。
2、在吞吐量和延遲方面性能很好。我們主數據中心,有針對非中國區的獨立服務,在2015年度高峰期間40臺服務器在170k QPS的負載情況下CPU只使用了35%。95%的響應時間小于5毫秒,99%的響應時間小于50毫秒。
3、超級穩定,這個服務自上線以來,99.99%的時間正常運轉。當機時間主要是由初學者的編程錯誤和第三方庫的文件描述符泄露導致。我們至今尚未遇到Go的運行時錯誤。


接下來?

過去Uber主要使用Node.js和Python,很多Uber新的服務開始選擇使用Go來創建。Go是Uber未來的趨勢,所以如果你對Go很有激情,無論是專家還是初學者,都歡迎你來應聘,我們正在招聘Go開發者,噢對了,傳送門請點這里!

?

圖片來源:“金門地鼠”,作者:Conor Myhrvold,攝于三藩市的金門公園。標題解釋:地鼠(Go gopher)是Go項目的吉祥物,是Go的標識。

?

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

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

相關文章

centos7:塔建pure_ftpd虛擬用戶

2019獨角獸企業重金招聘Python工程師標準>>> 1.下載pure_ftpd&#xff0c;上傳服務器,目錄路徑:/usr/local/src/ 下載地址:https://pan.baidu.com/s/1kWe8FAn 2.安裝pure_ftpd cd /usr/local/srctar -xjf pure-ftpd-1.0.36.tar.bz2cd pure-ftpd-1.0.36./configure -…

java.lang.module_如何修復“java.lang.module.FindException:module java.se.ee not found”錯誤

我正在嘗試打包我的kivy應用程序(python3)&#xff0c;但是當我運行命令buildozer -v android debug時&#xff0c;看到這個錯誤# Cwd /home/javier/.buildozer/android/platform/android-sdkError occurred during initialization of boot layerjava.lang.module.FindExceptio…

寒武紀芯片——有自己的SDK,支持tf、caffe、MXNet

寒武紀芯片產品中心>智能處理器IP智能處理器IP MLU智能芯片 軟件開發環境 Cambricon-1A 高性能硬件架構及軟件支持兼容Caffe、Tensorflow、MXnet等主流AI開發平臺&#xff0c;已多次成功流片 國際上首個成功商用的深度學習處理器IP產品&#xff0c;可廣泛應用于計算機視覺、…

maven ssm框架 mysql_SSM框架(IDEA+Spring+SpringMVC+Maven+Mybatis+MySQL)

【實例簡介】SSM框架(IDEASpringSpringMVCMavenMybatisMySQL),搭建SSM框架&#xff0c;利用mybatis-plus插件自動生成數據庫相關代碼。【實例截圖】【核心代碼】0d399d99-f108-4aaa-9c81-35b505c86e8a└── SSMManager├── pom.xml├── sql│ └── test.sql└── src…

spring框架的引入

spring框架給程序開發帶來了春天&#xff0c;在很多項目里&#xff0c;可能不用struts&#xff0c;不用hibernate&#xff0c;但往往都有spring。 why&#xff1f; 因為每個項目都會涉及到對象的創建和對象之間的依賴。 一、傳統的MVC開發 mvc的項目框架結構&#xff1a;Enti…

Java編程作業體會_Java作業的幾點總結感想

本次博客主要是總結近幾次作業&#xff0c;交流一下自己的感受。本次作業主要是對近幾次Java課程的鞏固作業&#xff0c;第一次作業主要是一些基礎的題目&#xff0c;包括選擇循環等一些基本語句&#xff0c;其目的在于掌握java一些基本知識&#xff0c;感受出Java與其他語言有…

基于百度語音識別API的Python語音識別小程序

一、功能概述 實現語音為文字&#xff0c;可以擴展到多種場景進行工作&#xff0c;這里只實現其基本的語言接收及轉換功能。 在語言錄入時&#xff0c;根據語言內容的多少與停頓時間&#xff0c;自動截取音頻進行轉換。 工作示例&#xff1a; 二、軟件環境 操作系統&#xff1a…

spring專業術語了解

組件/框架設計 侵入式設計 引入了框架&#xff0c;對現有的類的結構有影響&#xff1b;即需要實現或繼承某些特定類。 例如&#xff1a;Struts框架 非侵入式設計 引入了框架&#xff0c;對現有的類結構沒有影響。 例如&#xff1a;Hibernate框架 / Spring框架 控制反轉: In…

java修改ldap用戶密碼_LDAP 用戶更改自己的密碼

LDAP中采用了ACL的權限控制。在/etc/openldap/slapd.conf文件中&#xff1a;## See slapd.conf(5) for details on configuration options.# This file should NOT be world readable.#include/etc/openldap/schema/corba.schemainclude/etc/openldap/schema/core.schemainclud…

Spring第三篇【Core模塊之對象依賴】

tags: Spring 前言 在Spring的第二篇中主要講解了Spring Core模塊的使用IOC容器創建對象的問題&#xff0c;Spring Core模塊主要是解決對象的創建和對象之間的依賴關系&#xff0c;因此本博文主要講解如何使用IOC容器來解決對象之間的依賴關系&#xff01; 回顧以前對象依賴 我…

spring框架結構介紹

Spring提供了一站式解決方案&#xff1a; 1&#xff09; Spring Core spring的核心功能&#xff1a; IOC容器, 解決對象創建及依賴關系 2&#xff09; Spring Web Spring對web模塊的支持。 -->可以與struts整合,讓struts的action創建交給spring -->spring mvc模式 3…

java通過J2C獲取用戶名密碼_WAS服務器上的J2C別名有什么用途?

這是我LdapTemplate類 公共LdapTemplate getLdapTemplete(字符串ldapID) {WAS服務器上的J2C別名有什么用途&#xff1f;if (ldapID.equalsIgnoreCase(Constants.LDAP1)){if (ldapTemplate1 null){try{PasswordCredential passwordCredential j2cAliasUtility.getAliasDetails…

百度坐標轉換API使用

http://api.map.baidu.com/geoconv/v1/?coords121.54759,29.870724&from1&to5&aksGSOaO07WkRHHiCRxxbSQVBn 前提&#xff1a;121.54759,29.870724 是由手機硬件或谷歌地圖獲取的 錯誤的方法一&#xff1a; function standard2china(lng,lat){//http://api.map.ba…

Java語言所有異常類均繼承自_Java將運行錯誤分為兩類:(__)和(__), 其對應的類均派生自(__)類;...

【單選題】設 x,y 均為已定義的類名,下列聲明對象x1的語句中正確的是( )【判斷題】構造函數的方法名可以由編程人員任意命名。【單選題】能夠實現對原文的鑒別和不可否認性的認證技術是( )。【單選題】設有定義語句int a[]{66,88,99}; 則以下對此語句的敘述錯誤的是( )。【判斷…

Quartz業務類無法注入Spring對象問題

tags: 解決錯誤, titile: Quartz業務類無法注入Spring對象問題 Quartz業務類無法注入Spring對象問題 在剛開始遇到的時候還以為是Spring配置哪里錯誤了&#xff0c;結果搞了那么久&#xff0c;才知道Quartz與Spring注入對象是不關聯的。。 因為Quartz的業務Job對象是由Quartz來…

如何解決ajax跨域問題

原文&#xff1a;http://www.congmo.net/blog/2012/06/27/ajax-cross-domain/ 跨域問題 起 因是這樣的&#xff0c;為了復用&#xff0c;減少重復開發&#xff0c;單獨開發了一個用戶權限管理系統&#xff0c;共其他系統獲取認證與授權信息&#xff0c;暫且稱之為A系統&#xf…

spring bean創建細節

1) 對象創建&#xff1a; 單例/多例 scope"singleton", 默認值&#xff0c;即默認是單例【service/dao/工具類】 scope"prototype", 多例&#xff1b;【Action對象】 2) 什么時候創建? scope"prototype" 在用到對象的時候&#xff0c…

發送郵件程序報錯454 Authentication failed以及POP3和SMTP簡介

一、發現問題 在測試郵件發送程序的時候&#xff0c;發送給自己的QQ郵箱&#xff0c;程序報錯454 Authentication failed, please open smtp flag first。 二、解決問題 進入QQ郵箱——>設置——>賬戶——>POP3/IMAP/SMTP選擇——>開啟POP3/SMTP服務。 三、POP3和S…

MySQL數據庫是非關系_MySQL(數據庫)基礎知識、關系型數據庫yu非關系型數據庫、連接認證...

什么是數據庫&#xff1f;數據庫(Database)&#xff1a;存儲數據的倉庫高效地存儲和處理數據的介質(介質主要是兩種&#xff1a;磁盤和內存)數據庫系統&#xff1a;DBS(Database System)&#xff1a;是一種虛擬系統&#xff0c;將多種內容關聯起來的稱呼DBS DBMS DBDBMS&…

WPF 使用MahApps.Metro UI庫

http://www.cnblogs.com/happyyftk/p/6904766.html 本文示例源碼下載&#xff1a;MetroWPF 官方示例地址&#xff1a;http://mahapps.com/guides/quick-start.html 官方控件示例地址&#xff1a;http://mahapps.com/controls/ MahApps.Metro 項目源碼&#xff1a;https://githu…