京東熱key探測中間件單機qps 2萬升至35萬實錄,服了

2020-08-30 Java架構師公社

JD-hotkey

京東hotkey框架(JD-hotkey)是京東app後臺研發的一款高性能熱數據探測中間件,用來實時探測出系統的熱數據,並將熱數據毫秒內推送至系統的業務集群伺服器的JVM內存。以下統稱為&34;。

該框架主要用於對任意突發性的無法預先感知的熱key,包括並不限於熱點數據(如突發大量請求同一個商品)、熱用戶(如惡意爬蟲刷子)、熱接口(突發海量請求同一個接口)等,進行毫秒級精準探測到。然後對這些熱key,推送到所在服務端JVM內存中,以大幅減輕對後端數據存儲層的衝擊,並可以由使用者決定如何分配、使用這些熱key(譬如對熱商品做本地緩存、對熱用戶進行拒絕訪問、對熱接口進行熔斷或返回默認值)。這些熱數據在整個服務端集群內保持一致性,並且業務隔離,worker端性能強悍。

目前該框架已在京東App後臺、數據中臺、白條、金融、商家等多十餘個業務部門接入運行,目前應用最廣泛的場景是刷子(爬蟲)用戶實時探測和redis熱key實時探測。

由於框架自身核心點在於實時(準實時,可配置1-500ms內)探測系統運行中產生的熱key,而且還要面臨隨時可能突發的暴增流量(如突發搶購某商品),還要在探測出熱key後在毫秒時間內推送到該業務組的幾百、數千到上萬臺伺服器JVM內存中,所以對於它的單機性能要求非常高。

框架的計算單元worker端,它的工作流程是:啟動一個netty server,和業務伺服器(數百——上萬)建立長連接,業務伺服器批量定時(1——500ms一次)上傳自己的待測key給worker,worker對發來的key進行滑動窗口累加計算,達到用戶設置的閾值(如某個類型的key,pin_xxxx達到2秒20次),則將該key推送至整個業務伺服器集群內,從而業務伺服器可以在內存中使用這些熱key,到達設置的過期時間後會自動過期刪除。

截止目前,該框架0.4版本的性能表現如下(硬體配置為隨機機房創建的16核docker容器):

1 key探測計算:每秒可接收N臺伺服器發來的40多萬個待測key,並計算完畢其中的35萬左右。實測可每秒穩定計算30萬,極限計算37萬,超過的量會進入隊列等待。

2 熱key推送:當熱key產生後,對該業務集群所在長連接的伺服器進行key推送,每秒可穩定推送10-12萬次(毫秒內送達)。譬如1千臺伺服器,每秒該worker可以支撐產生100個熱key,即推送100*1000次。當每秒產生200個熱key,即每秒需要推送20萬次時,會出現有1s左右的延遲送達。強度壓測當每秒要推送50萬次時,出現了極其明顯的延遲,推送至client端的時間已不可控。在所有積壓的key推送完畢後,可繼續正常工作。

注意,推送是和接收30萬key並行的,也就是進和出加起來吞吐量在40多萬每秒。

以上為單機性能表現,通過橫向擴展,可以提升對應的處理量,不存在單點問題,橫向擴展中無性能瓶頸。以當前的性能表現,單機可以完成1000臺業務伺服器的熱key探測任務。系統設計之初,期望值是單機能支撐200臺業務器的日常計算,所以目前性能是高於預期的,在逐步的優化過程中,也遇到了很多問題,本文就是對這個過程中所遇到的與性能有關的問題和優化過程,做個記錄。

以下所有數據,不特殊指明的話,均默認是隨機機房的16核docker容器,屬於共享型資源,實際配置強於8核物理機,弱於16核物理機。

初始版本——2萬QPS

該版本採用的是jdk1.8.20(jdk的小版本影響很大),worker端採用的架構方式為netty默認參數+disruptor重複消費模式。

netty默認開啟cpu核數*2個線程,作為netty的工作線程,用於接收幾千臺機器發來的key,接收到待測key後,全部寫入到disruptor的生產者線程,生產者是單線程。之後disruptor同樣是cpu核數*2個消費者線程,每個消費者都重複消費每條發來的key。

這裡很明顯的問題,大家都能看到,disruptor為什麼要重複消費每個key?

因為當初的設想是將同一個key固定交給同一個線程進行累加計算,以避免多線程同時累加同一個key造成數量計算錯誤。所以每個消費者線程都全部消費所有的key,譬如8個線程,線程1隻處理key的hash值為1的,其他的return不處理。

該版本上線後,可連接3千臺業務伺服器,單機每秒處理幾千個key的情況下,cpu佔用率在20%多。猛一看,貌似還可以接受的樣子是嗎。

其實不是的,該版本隨後經歷了618大促壓測演練,首次壓測,該版本在壓測開始的一瞬間就已經生活不能自理了。

首次壓測量級只有10萬,我有4臺worker,平均每臺也就2萬多秒級key寫入,而cpu佔用率直接飆升至100%,系統卡的連10s一次的定時任務都不走了,完全殭屍狀態。

那麼問題在哪裡?僅通過猜測我們大概考慮是disruptor負載比較重,譬如是不是因為重複消費的問題?

要尋找問題在哪裡,進入容器內部,查看top的進程id,再使用top -H -p1234(1234為javaa進行pid),再使用jstack命令導出java各個線程的狀態。

在top -H這一步,我們看到有巨多的線程在佔用cpu,數量之多,令見者傷心、聞者落淚。

裡面有大量的如下

也就是說大量的disruptor消費者線程吃光了cpu,說好的百萬並發框架disruptor性能呢?

當然,這次的鍋不能給disruptor去背。這次的問題首要罪魁禍首是jdk版本問題,我們使用的1.8.0_20在docker容器內通過Runtime.getRuntime().availableProcessors()方法獲取到的數量是宿主機的核數,而不是分配的核數。

即便只分配這個容器4核8核,該方法取到的卻是宿主機的32核、64核,直接導致netty默認分配的高達128個線程,disruptor也是128個線程。這幾百個線程一開啟,平時空閒著就佔用20%多的cpu,壓測一開始,cpu直接原地起飛,忙於輪轉,瞬間癱瘓。

首次優化——10萬QPS

jdk在1.8.0_191之後,修復了容器內獲取cpu核數的問題,我們首先升級了jdk小版本,然後增加了對不同版本cpu核數的判斷邏輯,把線程數降了下來。

這其中我並沒有去修改disruptor所有線程都消費key的邏輯,保持了原樣。也就是說,16核機器,目前是32個netty IO線程,32個消費者業務線程。再次上線,cpu日常佔用率降低到7%-10%左右。

二次壓測開始,從下圖每10秒列印一次的日誌來看,單機秒級計算完畢的key在8萬多,同時秒級推送量在10萬左右。

此時cpu已經開始飄高了,當單機秒級達到14萬時,CPU接近跑滿狀態,此時已達線上平穩值上限10萬。其中佔用cpu較多的依舊是disruptor大量的線程。

二次優化——16萬QPS

考慮到線程數對性能影響還是很大,該應用作為純內存計算框架,是典型的cpu密集型,根本不需要那麼多的線程來做計算。

我大幅調低了netty的IO線程數和disruptor線程數,並隨後進行了多次實驗。首先netty的IO線程分別為4和8反覆測試,業務線程也調為4和8進行反覆測試。

最終得出結論,netty的IO線程在低於4時,秒級能接收到的key數量上限較低,4和8時區別不太大。而業務線程在高於8時,cpu佔用偏高。尤其是key發來的量比較少時,線程越多,cpu越高。注意,是發來的key更少,cpu更高,當完全沒有key發來時,cpu會比有key時更高。

原因在於disruptor它的策略就是會反覆輪詢隊列是否有可消費的數據,沒有數據時,它這個輪詢空耗cpu,即便等待策略是BlockingWaitStrategy。

所以,最終定下了IO線程和業務線程分別為8,即核數的一半。一半用來接收數據,一半用來做計算。

從圖上可以看到,秒級可以處理完畢16萬個key,cpu佔用率在40%。

加大壓力源後,實際處理量會繼續提升,但此時我對disruptor的實際表現並不滿意,總是在每百萬key左右就出現幾個發來的key在被消費時就已經超時(key發送時比key被處理時超過5秒)的情況。追查原因也無果,就是個別key好像是被遺忘在角落一樣,遲遲未被處理。

三次優化——25萬QPS

由於對disruptor不滿意,所以這一次直接丟棄了它,改為jdk自帶的LinkedBlockQueue,這是一個讀寫分別加鎖的隊列,比ArrayBlockQueue性能稍好,理論上不如disruptor性能好。

原因大家應該都清楚,首先ArrayBlockQueue讀寫同用一把鎖,LinkedBlockQueue是讀一把鎖、寫一把鎖,ArrayBlockQueue肯定是性能不如LinkedBlockQueue。

disruptor採用ringbuffer環形隊列,如果生產消費速率相當情況下,理論上讀寫均無鎖,是生產消費模型裡理論上性能最優的。然而,一切都要靠場景和最終成績來說話,網上拋開了這些單獨談框架性能其實沒有什麼意義。

同樣是8線程讀取key然後寫入到隊列,8線程是循環消費隊列。此時已經不會重複消費了,我採用了別的方式來避免多線程同時計算同一個key的數量累加問題。

再次上線後,首先非常明顯的變化就是再也沒有key被處理時發生超時的情況了,之前每百萬必出幾個,而這個Queue幾億也沒一個超時的,每個寫入都會迅速被消費。另一個非常直觀的感受就是cpu佔用率明顯下降。

在平時的日常生產環境,disruptor版在秒級幾千key,3千個長連接情況下,cpu佔用在7%-10%之間,不低於5%。而BlockQueue版上線後,日常同等狀態下,cpu佔用率0.5%-1%之間,即便是後來我加入了秒級監控這個單線程挺耗資源的邏輯(該邏輯會統計累加所有client每秒的key訪問數據,單線程cpu佔用單核50%以上),cpu佔用率也才在1.5%,不超過2%。

此時壓測可以看到,秒級處理量能達到25-30萬,cpu佔用率在70%。cpu整體處於比較穩定的狀態,該壓測持續N個小時,未見任何異常。

並且該版也進行過並發寫入同時對推送的壓測,穩定推送每秒10-12萬次可保持極其穩定毫秒級送達的狀態。在20萬次時開始出現延遲送達,極限每秒壓至48萬次推送,出現大量延遲,部分送達至業務client時延遲已超過5秒,此時我們認為熱key毫秒級推送功能在如此延遲下已不能達到既定目的。讀寫並行情況下,吞吐量在40萬左右。

這一版也是618大促期間線上運行的版本(秒級監控是618後加入的功能)。

最近優化——35萬QPS

之前所有版本,都是通過fastjson進行的序列化和反序列化,兩端通信時交互的對象都是fastjson序列化的字符串,採用netty的StringDecoder進行交互。

這種序列化和反序列化方式在平時使用中,性能處於足夠的狀態,幾千幾萬個小對象序列化耗時很少。大家都知道一些其他的序列化方式,如protobuf、msgPack等。

本地測試很容易,搞個只有幾個屬性的對象,做30萬次序列化、反序列化,對比json和protobuf的耗時區別。30萬次,大概相差個300-500ms的樣子,在兩小時幾乎沒什麼區別,但在30萬QPS時,差的就是這幾百ms。

網上相關評測序列化方式的文章也很多,可以自行找一些看看對比。

在更換序列化方式,修改netty編解碼器後,壓測如圖:

秒級16萬時,cpu大概25%。

秒級36.5萬時,cpu在50%的樣子。

此時,每秒壓力機發來的key在42萬以上,但處理量維持在36萬左右,不能繼續提升。因為多線程消費LinkedBlockQueue,已達到該組件性能上限。netty的IO線程尚未達到接收上限。

爭議項

其實從上面的生產消費圖大家都能看出來,所有netty收到的消息都發到了BlockQueue裡,這是唯一的隊列,生產消費者都是多線程,那麼必然是存在鎖競爭的。

很多人都會考慮為何不採用8個隊列,每個線程只往一個隊列發,消費者也只消費這一個線程。或者乾脆去掉隊列,直接消費netty收到的消息。這樣不就沒有所競爭了嗎,性能不就能再次起飛?

這個事情自然我也是多次測試過了,首先通過上面的壓測,我們知道瓶頸是在BlockQueue那裡,它一秒被8線程消費了37萬次,已經不能再高了,那麼8個隊列只要能超過這個數值,就代表這樣的優化是有效的。

然而實際測試結果並不讓人滿意,分發到8個隊列後,實際秒級處理量驟降至25萬浮動。至於直接在netty的IO線程做業務邏輯,這更不可取,如果不小心可能導致較為嚴重的積壓,甚至導致客戶端阻塞。

雖然網上很多文章都專門講鎖競爭導致性能下降,避免鎖來提升性能,但在這種30萬以上的場景下,實踐的重要性遠大於理論。至於為什麼會性能變差,就留給大家思考一下吧。

後記

可能大家覺得哇塞你這個調優好簡單,我也學會了,就是減少線程數,那麼實際是這樣嗎?

我們再來看看,線程少時導致吞吐量大幅下降的場景。

之前我們的測試都是說每秒收到了多少萬個key,處理了多少萬個key,大部分負載都是處理key上。現在我們來測試一下純推送量,只接收很少的key,然後讓所有的key都是熱key,開啟很多個客戶端,每秒推送很多次。

測試是這樣的,由一個單獨的client每秒發送1萬個key到單個worker,設置變熱規則為1,那麼這1萬個就全是熱key,然後我分別採用40、60、80、100個client端機器,這樣就意味著每秒單個worker要推送40、60、80、100萬次,通過觀察client端每秒是否接收到了1萬個熱key推送來判斷worker的推送極限。

首先還是使用上面的配置,即8個IO線程,8個消費者線程。

可以看到8線程在每秒推送40萬次時比較穩定,在client端打日誌也是基本1秒1萬個全部收到,沒有超時的情況。在60萬次時,cpu大幅抖動,大部分能及時推送到達,但開始出現部分超時送達的情況。上到60萬以上時,系統已不可用,大量的超時,所有信息都超時,開始出現推送積壓,堆外內存持續增長,逐漸內存溢出。

調大IO線程至16,推送量每秒60萬:

持續運行較長時間,cpu非常穩定,未出現8線程時那種偶爾大幅抖動的情況,穩定性比之前的8線程明顯好很多。

隨後我加大到80個客戶端,即每秒推送80萬次。

總體還是比較平穩,cpu來了60%附近,full gc開始變得頻繁起來,幾乎每20秒一次,但並未出現大量的超時情況,只有full gc那一刻,會有個別key在到達client時超過1秒。系統開始出現不穩定的情況。

我加大到100個client,即每秒要推送100萬次。

此時系統已經明顯不堪重負,full gc非常密集,cpu開始大幅抖動,大量的1秒超時,整體已經不可控了,持續運行後,就會開始出異常,內存溢出等問題。

通過對純推送的壓測,發現更多的IO線程,幾乎可以到達每秒70萬推送穩定,比8線程的時候40多萬穩定,強了不是一點點。同樣一臺機器,僅改了改線程數量而已。

那麼問題又來了,我們應該怎麼去配置這個線程數量呢?

那麼就有實際場景了,你是到底每秒有很多key要探測、但是熱的不多,還是探測量一般般、但是閾值調的低、熱key產生多、需要每秒推送很多次。歸根到底,是要把計算資源讓給IO線程多一些,還是消費者線程多一些的問題。

總結

在開發過程中,遇到了諸多問題,遠不止上面調個線程數那麼簡單,對很多數據結構、包傳輸、並發、和客戶端的連接處理很多地方都出過問題,也對很多地方選型做過權衡,線上以求穩為主,穩中有性能提升是最好的。

主要的結論就是一切靠實踐,任何理論、包括書上寫的、博客寫的,很多是靠想像,平時本地運行多久都不出問題,拿到線上,百萬流量一衝擊,各種奇奇怪怪的問題。有些在被衝擊後,過一會能恢復服務,而有些技術就不行了,就直接癱瘓只能重啟,甚至於連個異常信息都沒有,就那麼安安靜靜的停止響應了。

線上真實流量+極端暴力壓測是我們在每一個微小改動後都會去做的事情,力求服務極端流量不宕機、不誤判。

目前該框架已在開源中國發布開源,https://gitee.com/jd-platform-opensource/hotkey,有相關熱key痛點需求的可以了解一下,有定製化需求,或不滿足自己場景的也可以反饋,我們也在積極採納內外部意見建議,共建優質框架。

本文轉自gitee,如果對您有幫助的話,關注我一起向大佬學習。

相關焦點

  • 京東開源熱key探測中間件單機qps,2萬提升至35萬實錄
    京東 hotkey 框架(JD-hotkey)是京東app後臺研發的一款高性能熱數據探測中間件,用來實時探測出系統的熱數據,並將熱數據毫秒內推送至系統的業務集群伺服器的JVM內存。以下統稱為"熱key"。
  • 京東開源熱key探測中間件單機qps,2萬提升至35萬實錄
    important}京東 hotkey 框架(JD-hotkey)是京東app後臺研發的一款高性能熱數據探測中間件,用來實時探測出系統的熱數據,並將熱數據毫秒內推送至系統的業務集群伺服器的JVM內存。以下統稱為&34;。
  • 京東熱 key 探測框架新版發布,單機 QPS 可達 35 萬
    京東的熱key探測前面簡單介紹了熱key的發現與解決,這種問題其實最明顯的發生就是在電商系統或者像微博這種社交系統中。所以很多公司內部也有很多成熟的方案。今天想介紹一個京東內部的框架——JD-hotkey ,這是京東 APP 後臺熱數據探測框架。
  • 京東開源,秒殺,限流,中間件,單機QPS 提升至 37 萬
    worker單機性能從618大促穩定版的20萬QPS穩定,30萬極限,提升至30萬穩定,37萬極限。且cpu峰值下降了15%。該中間件目前在京東內部10餘個核心部門接入使用,服務於京東App服務端前臺、中臺,數據中臺等多個核心業務線。
  • 京東毫秒級熱 key 探測框架設計與實踐,已實戰於618大促
    2)改寫redis源碼加入熱點探測功能,有熱key時推送到jvm。問題主要是不通用,且有一定難度。3)改寫jedis、letture等redis客戶端的jar,通過本地計算來探測熱點key,是熱key的就本地緩存起來並通知集群內其他機器。
  • 京東毫秒級熱 key 探測框架設計與實踐,已實戰於 618 大促
    2)改寫redis源碼加入熱點探測功能,有熱key時推送到jvm。問題主要是不通用,且有一定難度。3)改寫jedis、letture等redis客戶端的jar,通過本地計算來探測熱點key,是熱key的就本地緩存起來並通知集群內其他機器。
  • 京東App後臺中間件,毫秒級推送至伺服器集群內存 源碼分享
    京東APP後臺熱數據探測框架,歷經多次高壓壓測和2020年京東618大促考驗。在上線運行的這段時間內,每天探測的key數量數十億計,精準捕獲了大量爬蟲、刷子用戶,另準確探測大量熱門商品並毫秒級推送到各個服務端內存,大幅降低了熱數據對數據層的查詢壓力,提升了應用性能。
  • 京東熱 key 探測 HotKey 0.4 發布,單機 QPS 提升至 35 萬
  • 京東618壓測時自研中間件暴露出的問題,壓測級別數十萬/秒
    618大促演練進行了全鏈路壓測,在此之前剛好我的熱key探測框架也已經上線灰度一周了,小範圍上線了幾千臺伺服器,每秒大概接收幾千個key探測,每天大概幾億左右,因為量很小,所以框架表現穩定。借著這次壓測,剛好可以檢驗一下熱key框架在大流量時的表現。畢竟作為一個新的中間件,裡面很多東西還是第一次用,免不得會出一些問題。
  • 京東618壓測時自研中間件暴露出的問題總結,壓測級別數十萬/秒
    618大促演練進行了全鏈路壓測,在此之前剛好我的熱key探測框架也已經上線灰度一周了,小範圍上線了幾千臺伺服器,每秒大概接收幾千個key探測,每天大概幾億左右,因為量很小,所以框架表現穩定。借著這次壓測,剛好可以檢驗一下熱key框架在大流量時的表現。畢竟作為一個新的中間件,裡面很多東西還是第一次用,免不得會出一些問題。
  • 鄧紫棋升key上熱搜了?是怎麼回事?
    #鄧紫棋升key# 鄧紫棋直播演唱《光年之外》,連升8個key,被@GEM鄧紫棋 的高音震撼了芒果娛樂超話 芒果娛樂的微博視頻 鄧紫棋升key 光年之外連升8個key!連升8key 實力我解NB,吹爆!!!我感覺我配不上她。其實鄧紫棋就這樣的髮型也超好看的,好喜歡她!!!
  • Doulive沙發音樂會,鄧紫棋挑戰《光年之外》連升八key喜提雙熱搜
    2月21日晚,歌手G.E.M.鄧紫棋現身Doulive抖音沙發音樂會,開播一分鐘在線觀看人數便突破十萬,並保持每分鐘一萬的速度瘋狂飆升,最高同時在線觀看人數超41萬人次,成功登頂抖音直播小時榜。此外,「鄧紫棋光年之外連升8key」、「鄧紫棋升key」也分別登上了抖音和微博的熱搜TOP榜,話題討論度十分火熱。
  • QPS過萬,redis大量連接超時怎麼解決?
    7月2號10點後,剛好某個負責的服務發生大量的redis連接超時的異常(redis.clients.jedis.exceptions.JedisConnectionException),由於本身的資料庫查詢緩存在redis中2分鐘,並且未做降級措施,而且本身不能做限流處理,而且隨著午高峰的時間流量在飆升,並且從10點開始的2000的QPS,在11點達到高峰的13000QPS。
  • 尼康keyMission運動相機京東首發,任性豪禮大放送
    為滿足廣大消費者的購買訴求,京東在尼康keyMission運動相機預約期間,打造了一系列優惠豪禮:預約即有機會參加抽獎贏得單眼相機,還有白條12期免息、曬單送Nikon限量版戶外保溫壺等活動。想要搶鮮入手尼康keyMission運動相機,即刻上京東開始預約吧!  活動連結:http://sale.jd.com/act/x65BT0jkrSAXa.html
  • 百度,京東,阿里等IT大廠如何做Redis集群方案
    :讀寫請求訪問 src 節點,處理後訪問:訪問的 key 正在遷移:讀請求訪問 src 節點後直接返回; 寫請求無法處理,返回 retry訪問的 key 已被遷移 (或不存在):讀寫請求訪問 src 節點,收到 moved 回復,繼續訪問 target 節點處理阿里雲AparaCache 的單機版已開源 (開源版本中不包含 slot 等實現),
  • Canon/佳能7D Mark II(單機 2020萬有效像素 全高清1080) 京東7888元
    目前這款相機正在京東 美康數碼攝影專營店火熱銷售中,價格僅為7888元,喜歡的朋友可以關注一下。外形尺寸為148.6×112.4×78.2mm。佳能7DMarkII相機顯示屏類型為高清屏,顯示屏尺寸為3英寸,顯示屏像素為104萬像素液晶屏,實時取景支持,方便拍攝時從不同角度取景,視野覆蓋廣泛。       佳能7DMarkII相機存儲卡類型支持SD/SDHC/SDXC卡/CF卡(兼容UHS-I),文件格式:支持圖片:JPEG,RAW,JPEG+RAW,視頻:MOV,MP4。
  • 佳能800D 單機 2420萬有效像素 全高清1080 京東4345元(贈品)
    目前這款相機正在京東 華聿攝影專營店火熱銷售中,價格僅為4345元,現在下單即送國產電池,送完即止,喜歡的朋友可以關注一下。外形尺寸為131×99.9×76.2mm。佳能800D相機顯示屏類型為觸控螢幕,顯示屏像素為104萬像素液晶屏。       佳能800D相機存儲卡類型支持SD/SDHC/SDXC卡(兼容UHS-I),文件格式:支持圖像:JPEG,RAW,RAW+JPEG,短片:MP4,MPEG-4 AVC/H.264,音頻:AAC。
  • 數據同步中間件 Porter 3.0 發布,新增單機模式
    數據同步中間件 Porter 3.0發布。
  • 佳能5Ds R(單機 約5060萬像素 3.2英寸液晶屏 消除低通濾鏡) 京東...
    佳能5DsR於2015年06月上市,佳能5DsR是一款擁有5060萬的有效像素目前這款相機正在京東 佳能影像官方旗艦店火熱銷售中,價格僅為13999元,喜歡的朋友可以關注一下。佳能5DsR相機曝光補償:±5EV(1/3EV或1/2EV步長),白平衡:自動,預設(日光,陰影,陰天,鎢絲燈,白色螢光燈,閃光燈),用戶自定義,色溫(約2500-10000K),白平衡校正和白平衡包圍曝光,感光度為場景智能自動:在ISO 100-3200之間自動設置,P,Tv,Av,M,B:自動ISO,可在ISO 100-6400範圍內手動設置(以1/3級或整級為單位),或ISO感光度擴展到L(相當於
  • 2430w像素全幅單電 索尼A99單機京東促銷
    (中關村在線數碼影像行情報導)索尼A99並不是一款單眼相機,而是採用半透鏡光學結構的單電相機,值得一提的是它採用了全畫幅的CMOS圖像傳感器,有效像素高達2400萬。目前京東商城在進行促銷活動,索尼A99的促銷價格為14699元。