<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ivaneeo's blog

    自由的力量,自由的生活。

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

    #

    本文有標題黨之嫌。在NoSQL如日中天的今天,各種NoSQL產品可謂百花齊放,但每一個產品都有自己的特點,有長處也有不適合的場景。本文對CassandraMongodbCouchDBRedisRiak 以及 HBase 進行了多方面的特點分析,希望看完此文的您能夠對這些NoSQL產品的特性有所了解。

    CouchDB

    • Written in: Erlang
    • Main point: DB consistency, ease of use
    • License: Apache
    • Protocol: HTTP/REST
    • Bi-directional (!) replication,
    • continuous or ad-hoc,
    • with conflict detection,
    • thus, master-master replication. (!)
    • MVCC – write operations do not block reads
    • Previous versions of documents are available
    • Crash-only (reliable) design
    • Needs compacting from time to time
    • Views: embedded map/reduce
    • Formatting views: lists & shows
    • Server-side document validation possible
    • Authentication possible
    • Real-time updates via _changes (!)
    • Attachment handling
    • thus, CouchApps (standalone js apps)
    • jQuery library included

    Best used: For accumulating, occasionally changing data, on which pre-defined queries are to be run. Places where versioning is important.

    For example: CRM, CMS systems. Master-master replication is an especially interesting feature, allowing easy multi-site deployments.

    Redis

    • Written in: C/C++
    • Main point: Blazing fast
    • License: BSD
    • Protocol: Telnet-like
    • Disk-backed in-memory database,
    • but since 2.0, it can swap to disk.
    • Master-slave replication
    • Simple keys and values,
    • but complex operations like ZREVRANGEBYSCORE
    • INCR & co (good for rate limiting or statistics)
    • Has sets (also union/diff/inter)
    • Has lists (also a queue; blocking pop)
    • Has hashes (objects of multiple fields)
    • Of all these databases, only Redis does transactions (!)
    • Values can be set to expire (as in a cache)
    • Sorted sets (high score table, good for range queries)
    • Pub/Sub and WATCH on data changes (!)

    Best used: For rapidly changing data with a foreseeable database size (should fit mostly in memory).

    For example: Stock prices. Analytics. Real-time data collection. Real-time communication.

    MongoDB

    • Written in: C++
    • Main point: Retains some friendly properties of SQL. (Query, index)
    • License: AGPL (Drivers: Apache)
    • Protocol: Custom, binary (BSON)
    • Master/slave replication
    • Queries are javascript expressions
    • Run arbitrary javascript functions server-side
    • Better update-in-place than CouchDB
    • Sharding built-in
    • Uses memory mapped files for data storage
    • Performance over features
    • After crash, it needs to repair tables
    • Better durablity coming in V1.8

    Best used: If you need dynamic queries. If you prefer to define indexes, not map/reduce functions. If you need good performance on a big DB. If you wanted CouchDB, but your data changes too much, filling up disks.

    For example: For all things that you would do with MySQL or PostgreSQL, but having predefined columns really holds you back.

    Cassandra

    • Written in: Java
    • Main point: Best of BigTable and Dynamo
    • License: Apache
    • Protocol: Custom, binary (Thrift)
    • Tunable trade-offs for distribution and replication (N, R, W)
    • Querying by column, range of keys
    • BigTable-like features: columns, column families
    • Writes are much faster than reads (!)
    • Map/reduce possible with Apache Hadoop
    • I admit being a bit biased against it, because of the bloat and complexity it has partly because of Java (configuration, seeing exceptions, etc)

    Best used: When you write more than you read (logging). If every component of the system must be in Java. (“No one gets fired for choosing Apache’s stuff.”)

    For example: Banking, financial industry (though not necessarily for financial transactions, but these industries are much bigger than that.) Writes are faster than reads, so one natural niche is real time data analysis.

    Riak

    • Written in: Erlang & C, some Javascript
    • Main point: Fault tolerance
    • License: Apache
    • Protocol: HTTP/REST
    • Tunable trade-offs for distribution and replication (N, R, W)
    • Pre- and post-commit hooks,
    • for validation and security.
    • Built-in full-text search
    • Map/reduce in javascript or Erlang
    • Comes in “open source” and “enterprise” editions

    Best used: If you want something Cassandra-like (Dynamo-like), but no way you’re gonna deal with the bloat and complexity. If you need very good single-site scalability, availability and fault-tolerance, but you’re ready to pay for multi-site replication.

    For example: Point-of-sales data collection. Factory control systems. Places where even seconds of downtime hurt.

    HBase

    • Written in: Java
    • Main point: Billions of rows X millions of columns
    • License: Apache
    • Protocol: HTTP/REST (also Thrift)
    • Modeled after BigTable
    • Map/reduce with Hadoop
    • Query predicate push down via server side scan and get filters
    • Optimizations for real time queries
    • A high performance Thrift gateway
    • HTTP supports XML, Protobuf, and binary
    • Cascading, hive, and pig source and sink modules
    • Jruby-based (JIRB) shell
    • No single point of failure
    • Rolling restart for configuration changes and minor upgrades
    • Random access performance is like MySQL

    Best used: If you’re in love with BigTable. :) And when you need random, realtime read/write access to your Big Data.

    For example: Facebook Messaging Database (more general example coming soon)

    原文鏈接:Cassandra vs MongoDB vs CouchDB vs Redis vs Riak vs HBase comparison

    posted @ 2011-07-05 15:11 ivaneeo 閱讀(1261) | 評論 (0)編輯 收藏

    xStream性能不高,參考
    https://github.com/eishay/jvm-serializers/wiki
    如果純java場景應用,可以參考kryo
    如果需要跨語言,可以參考ProtoBuf
    posted @ 2011-07-01 23:33 ivaneeo 閱讀(326) | 評論 (0)編輯 收藏

    如果有不明白的地方或者陌生的端口可以在這里查到。以便于檢查系統是否感染病毒或木馬。但是在有防火墻的情況下,一般的防火墻都是嚴格審核程序的網絡連接 的,所以會預先封閉所有的端口,有需要訪問網絡的程序會預先向防火墻提出申請,防火墻做出響應,并彈出提示,要求用戶做出選擇,這時候我們就要認真看了, 是哪一個程序,在文件夾的哪一個位置,要做一個估計,陌生程序就更要檢查。這樣才能不給惡意程序任何余地。同時系統自動升級最好打開,或者定期到 windows的微軟網站下載系統更新程序,這樣也非常有利于系統安全。系統漏洞可能會使惡意程序通過系統漏洞繞過防火墻連接到網絡。

    端口:1
    服務:tcpmux
    說 明:這顯示有人在尋找sgi irix機器。irix是實現tcpmux的主要提供者,默認情況下tcpmux在這種系統中被打開。irix機器在發布是含有幾個默認的無密碼的帳戶, 如:ip、guest uucp、nuucp、demos 、tutor、diag、outofbox等。許多管理員在安裝后忘記刪除這些帳戶。因此hacker在internet上搜索tcpmux并利用這些帳 戶。

    端口:7
    服務:echo
    說明:能看到許多人搜索fraggle放大器時,發送到x.x.x.0和x.x.x.255的信息。

    端口:19
    服務:character generator
    說 明:這是一種僅僅發送字符的服務。udp版本將會在收到udp包后回應含有**字符的包。tcp連接時會發送含有**字符的數據流直到連接關閉。 hacker利用ip欺騙可以發動dos攻擊。偽造兩個chargen服務器之間的udp包。同樣fraggle dos攻擊向目標地址的這個端口廣播一個帶有偽造受害者ip的數據包,受害者為了回應這些數據而過載。

    端口:21
    服務:ftp
    說 明:ftp服務器所開放的端口,用于上傳、下載。最常見的攻擊者用于尋找打開anonymous的ftp服務器的方法。這些服務器帶有可讀寫的目錄。木馬 doly trojan、fore、invisible ftp、webex、wincrash和blade runner所開放的端口。

    端口:22
    服務:ssh
    說明:pcanywhere建立的tcp和這一端口的連接可能是為了尋找ssh。這一服務有許多弱點,如果配置成特定的模式,許多使用rsaref庫的版本就會有不少的漏洞存在。

    端口:23
    服務:telnet
    說明:遠程登錄,入侵者在搜索遠程登錄unix的服務。大多數情況下掃描這一端口是為了找到機器運行的操作系統。還有使用其他技術,入侵者也會找到密碼。木馬tiny telnet server就開放這個端口。

    端口:25
    服務:smtp
    說 明:smtp服務器所開放的端口,用于發送郵件。入侵者尋找smtp服務器是為了傳遞他們的spam。入侵者的帳戶被關閉,他們需要連接到高帶寬的 e-mail服務器上,將簡單的信息傳遞到不同的地址。木馬antigen、email password sender、haebu coceda、shtrilitz stealth、winpc、winspy都開放這個端口。

    端口:31
    服務:msg authentication
    說明:木馬master paradise、hackers paradise開放此端口。

    端口:42
    服務:wins replication
    說明:wins復制

    端口:53
    服務:domain name server(dns)
    說明:dns服務器所開放的端口,入侵者可能是試圖進行區域傳遞(tcp),欺騙dns(udp)或隱藏其他的通信。因此防火墻常常過濾或記錄此端口。

    端口:67
    服務:bootstrap protocol server
    說 明:通過dsl和cable modem的防火墻常會看見大量發送到廣播地址255.255.255.255的數據。這些機器在向dhcp服務器請求一個地址。hacker常進入它 們,分配一個地址把自己作為局部路由器而發起大量中間人(man-in-middle)攻擊。客戶端向68端口廣播請求配置,服務器向67端口廣播回應請 求。這種回應使用廣播是因為客戶端還不知道可以發送的ip地址。

    端口:69
    服務:trival file transfer
    說明:許多服務器與bootp一起提供這項服務,便于從系統下載啟動代碼。但是它們常常由于錯誤配置而使入侵者能從系統中竊取任何 文件。它們也可用于系統寫入文件。

    端口:79
    服務:finger server
    說明:入侵者用于獲得用戶信息,查詢操作系統,探測已知的緩沖區溢出錯誤,回應從自己機器到其他機器finger掃描。

    端口:80
    服務:http
    說明:用于網頁瀏覽。木馬executor開放此端口。

    端口:99
    服務:metagram relay
    說明:后門程序ncx99開放此端口。

    端口:102
    服務:message transfer agent(mta)-x.400 over tcp/ip
    說明:消息傳輸代理。

    端口:109
    服務:post office protocol -version3
    說明:pop3服務器開放此端口,用于接收郵件,客戶端訪問服務器端的郵件服務。pop3服務有許多公認的弱點。關于用戶名和密碼交 換緩沖區溢出的弱點至少有20個,這意味著入侵者可以在真正登陸前進入系統。成功登陸后還有其他緩沖區溢出錯誤。

    端口:110
    服務:sun公司的rpc服務所有端口
    說明:常見rpc服務有rpc.mountd、nfs、rpc.statd、rpc.csmd、rpc.ttybd、amd等

    端口:113
    服務:authentication service
    說 明:這是一個許多計算機上運行的協議,用于鑒別tcp連接的用戶。使用標準的這種服務可以獲得許多計算機的信息。但是它可作為許多服務的記錄器,尤其是 ftp、pop、imap、smtp和irc等服務。通常如果有許多客戶通過防火墻訪問這些服務,將會看到許多這個端口的連接請求。記住,如果阻斷這個端 口客戶端會感覺到在防火墻另一邊與e-mail服務器的緩慢連接。許多防火墻支持tcp連接的阻斷過程中發回rst。這將會停止緩慢的連接。

    端口:119
    服務:network news transfer protocol
    說明:news新聞組傳輸協議,承載usenet通信。這個端口的連接通常是人們在尋找usenet服務器。多數isp限制,只有他們的客戶才能訪問他們的新聞組服務器。打開新聞組服務器將允許發/讀任何人的帖子,訪問被限制的新聞組服務器,匿名發帖或發送spam。

    端口:135
    服務:本地 service
    說 明:microsoft在這個端口運行dce rpc end-point mapper為它的dcom服務。這與unix 111端口的功能很相似。使用dcom和rpc的服務利用計算機上的end-point mapper注冊它們的位置。遠端客戶連接到計算機時,它們查找end-point mapper找到服務的位置。hacker掃描計算機的這個端口是為了找到這個計算機上運行exchange server嗎?什么版本?還有些dos攻擊直接針對這個端口。

    端口:137、138、139
    服務:netbios name service
    說明:其中137、138是udp端口,當通過網上鄰居傳輸文件時用這個端口。而139端口:通過這個端口進入的連接試圖獲得netbios/smb服務。這個協議被用于windows文件和打印機共享和samba。還有wins regisrtation也用它。

    端口:143
    服務:interim mail access protocol v2
    說 明:和pop3的安全問題一樣,許多imap服務器存在有緩沖區溢出漏洞。記住:一種linux蠕蟲(admv0rm)會通過這個端口繁殖,因此許多這個 端口的掃描來自不知情的已經被感染的用戶。當redhat在他們的linux發布版本中默認允許imap后,這些漏洞變的很流行。這一端口還被用于 imap2,但并不流行。

    端口:161
    服務:snmp
    說明:snmp允許遠程管理設備。所有配置和運行信息的儲存 在數據庫中,通過snmp可獲得這些信息。許多管理員的錯誤配置將被暴露在internet。cackers將試圖使用默認的密碼public、 private訪問系統。他們可能會試驗所有可能的組合。snmp包可能會被錯誤的指向用戶的網絡。

    端口:177
    服務:x display manager control protocol
    說明:許多入侵者通過它訪問x-windows操作臺,它同時需要打開6000端口。

    端口:389
    服務:ldap、ils
    說明:輕型目錄訪問協議和netmeeting internet locator server共用這一端口。

    端口:443
    服務:https
    說明:網頁瀏覽端口,能提供加密和通過安全端口傳輸的另一種http。

    端口:456
    服務:【null】
    說明:木馬hackers paradise開放此端口。

    端口:513
    服務:login,remote login
    說明:是從使用cable modem或dsl登陸到子網中的unix計算機發出的廣播。這些人為入侵者進入他們的系統提供了信息。

    端口:544
    服務:【null】
    說明:kerberos kshell

    端口:548
    服務:macintosh,file services(afp/ip)
    說明:macintosh,文件服務。

    端口:553
    服務:corba iiop (udp)
    說明:使用cable modem、dsl或vlan將會看到這個端口的廣播。corba是一種面向對象的rpc系統。入侵者可以利用這些信息進入系統。

    端口:555
    服務:dsf
    說明:木馬phase1.0、stealth spy、inikiller開放此端口。

    端口:568
    服務:membership dpa
    說明:成員資格 dpa。

    端口:569
    服務:membership msn
    說明:成員資格 msn。

    端口:635
    服務:mountd
    說 明:linux的mountd bug。這是掃描的一個流行bug。大多數對這個端口的掃描是基于udp的,但是基于tcp的mountd有所增加(mountd同時運行于兩個端口)。 記住mountd可運行于任何端口(到底是哪個端口,需要在端口111做portmap查詢),只是linux默認端口是635,就像nfs通常運行于 2049端口。

    端口:636
    服務:ldap
    說明:ssl(secure sockets layer)

    端口:666
    服務:doom id software
    說明:木馬attack ftp、satanz backdoor開放此端口

    端口:993
    服務:imap
    說明:ssl(secure sockets layer)

    端口:1001、1011
    服務:【null】
    說明:木馬silencer、webex開放1001端口。木馬doly trojan開放1011端口。

    端口:1024
    服務:reserved
    說 明:它是動態端口的開始,許多程序并不在乎用哪個端口連接網絡,它們請求系統為它們分配下一個閑置端口。基于這一點分配從端口1024開始。這就是說第一 個向系統發出請求的會分配到1024端口。你可以重啟機器,打開telnet,再打開一個窗口運行natstat -a 將會看到telnet被分配1024端口。還有sql session也用此端口和5000端口。

    端口:1025、1033
    服務:1025:network blackjack 1033:【null】
    說明:木馬netspy開放這2個端口。

    端口:1080
    服務:socks
    說 明:這一協議以通道方式穿過防火墻,允許防火墻后面的人通過一個ip地址訪問internet。理論上它應該只允許內部的通信向外到達internet。 但是由于錯誤的配置,它會允許位于防火墻外部的攻擊穿過防火墻。wingate常會發生這種錯誤,在加入irc聊天室時常會看到這種情況。
    端口:1170
    服務:【null】
    說明:木馬streaming audio trojan、psyber stream server、voice開放此端口。

    端口:1234、1243、6711、6776
    服務:【null】
    說明:木馬subseven2.0、ultors trojan開放1234、6776端口。木馬subseven1.0/1.9開放1243、6711、6776端口。

    端口:1245
    服務:【null】
    說明:木馬vodoo開放此端口。

    端口:1433
    服務:sql
    說明:microsoft的sql服務開放的端口。

    端口:1492
    服務:stone-design-1
    說明:木馬ftp99cmp開放此端口。

    端口:1500
    服務:rpc client fixed port session queries
    說明:rpc客戶固定端口會話查詢

    端口:1503
    服務:netmeeting t.120
    說明:netmeeting t.120

    端口:1524
    服務:ingress
    說 明:許多攻擊腳本將安裝一個后門shell于這個端口,尤其是針對sun系統中sendmail和rpc服務漏洞的腳本。如果剛安裝了防火墻就看到在這個 端口上的連接企圖,很可能是上述原因。可以試試telnet到用戶的計算機上的這個端口,看看它是否會給你一個shell。連接到 600/pcserver也存在這個問題。

    端口:1600
    服務:issd
    說明:木馬shivka-burka開放此端口。

    端口:1720
    服務:netmeeting
    說明:netmeeting h.233 call setup。

    端口:1731
    服務:netmeeting audio call control
    說明:netmeeting音頻調用控制。

    端口:1807
    服務:【null】
    說明:木馬spysender開放此端口。

    端口:1981
    服務:【null】
    說明:木馬shockrave開放此端口。

    端口:1999
    服務:cisco identification port
    說明:木馬backdoor開放此端口。

    端口:2000
    服務:【null】
    說明:木馬girlfriend 1.3、millenium 1.0開放此端口。

    端口:2001
    服務:【null】
    說明:木馬millenium 1.0、trojan cow開放此端口。

    端口:2023
    服務:xinuexpansion 4
    說明:木馬pass ripper開放此端口。

    端口:2049
    服務:nfs
    說明:nfs程序常運行于這個端口。通常需要訪問portmapper查詢這個服務運行于哪個端口。

    端口:2115
    服務:【null】
    說明:木馬bugs開放此端口。

    端口:2140、3150
    服務:【null】
    說明:木馬deep throat 1.0/3.0開放此端口。

    端口:2500
    服務:rpc client using a fixed port session replication
    說明:應用固定端口會話復制的rpc客戶

    端口:2583
    服務:【null】
    說明:木馬wincrash 2.0開放此端口。

    端口:2801
    服務:【null】
    說明:木馬phineas phucker開放此端口。

    端口:3024、4092
    服務:【null】
    說明:木馬wincrash開放此端口。

    端口:3128
    服務:squid
    說 明:這是squid http代理服務器的默認端口。攻擊者掃描這個端口是為了搜尋一個代理服務器而匿名訪問internet。也會看到搜索其他代理服務器的端口8000、 8001、8080、8888。掃描這個端口的另一個原因是用戶正在進入聊天室。其他用戶也會檢驗這個端口以確定用戶的機器是否支持代理。

    端口:3129
    服務:【null】
    說明:木馬master paradise開放此端口。

    端口:3150
    服務:【null】
    說明:木馬the invasor開放此端口。

    端口:3210、4321
    服務:【null】
    說明:木馬schoolbus開放此端口

    端口:3333
    服務:dec-notes
    說明:木馬prosiak開放此端口

    端口:3389
    服務:超級終端
    說明:windows 2000終端開放此端口。

    端口:3700
    服務:【null】
    說明:木馬portal of doom開放此端口

    端口:3996、4060
    服務:【null】
    說明:木馬remoteanything開放此端口

    端口:4000
    服務:qq客戶端
    說明:騰訊qq客戶端開放此端口。

    端口:4092
    服務:【null】
    說明:木馬wincrash開放此端口。

    端口:4590
    服務:【null】
    說明:木馬icqtrojan開放此端口。

    端口:5000、5001、5321、50505
    服務:【null】
    說明:木馬blazer5開放5000端口。木馬sockets de troie開放5000、5001、5321、50505端口。

    端口:5400、5401、5402
    服務:【null】
    說明:木馬blade runner開放此端口。

    端口:5550
    服務:【null】
    說明:木馬xtcp開放此端口。

    端口:5569
    服務:【null】
    說明:木馬robo-hack開放此端口。

    端口:5632
    服務:pcanywere
    說 明:有時會看到很多這個端口的掃描,這依賴于用戶所在的位置。當用戶打開pcanywere時,它會自動掃描局域網c類網以尋找可能的代理(這里的代理是 指agent而不是proxy)。入侵者也會尋找開放這種服務的計算機。,所以應該查看這種掃描的源地址。一些搜尋pcanywere的掃描包常含端口 22的udp數據包。

    端口:5742
    服務:【null】
    說明:木馬wincrash1.03開放此端口。

    端口:6267
    服務:【null】
    說明:木馬廣外女生開放此端口。

    端口:6400
    服務:【null】
    說明:木馬the thing開放此端口。

    端口:6670、6671
    服務:【null】
    說明:木馬deep throat開放6670端口。而deep throat 3.0開放6671端口。

    端口:6883
    服務:【null】
    說明:木馬deltasource開放此端口。

    端口:6969
    服務:【null】
    說明:木馬gatecrasher、priority開放此端口。

    端口:6970
    服務:realaudio
    說明:realaudio客戶將從服務器的6970-7170的udp端口接收音頻數據流。這是由tcp-7070端口外向控制連接設置的。

    端口:7000
    服務:【null】
    說明:木馬remote grab開放此端口。

    端口:7300、7301、7306、7307、7308
    服務:【null】
    說明:木馬netmonitor開放此端口。另外netspy1.0也開放7306端口。

    端口:7323
    服務:【null】
    說明:sygate服務器端。

    端口:7626
    服務:【null】
    說明:木馬giscier開放此端口。

    端口:7789
    服務:【null】
    說明:木馬ickiller開放此端口。

    端口:8000
    服務:oicq
    說明:騰訊qq服務器端開放此端口。

    端口:8010
    服務:wingate
    說明:wingate代理開放此端口。

    端口:8080
    服務:代理端口
    說明:www代理開放此端口。

    端口:9400、9401、9402
    服務:【null】
    說明:木馬incommand 1.0開放此端口。

    端口:9872、9873、9874、9875、10067、10167
    服務:【null】
    說明:木馬portal of doom開放此端口。

    端口:9989
    端口:9989
    服務:【null】
    說明:木馬ini-killer開放此端口。

    端口:11000
    服務:【null】
    說明:木馬sennaspy開放此端口。

    端口:11223
    服務:【null】
    說明:木馬progenic trojan開放此端口。

    端口:12076、61466
    服務:【null】
    說明:木馬telecommando開放此端口。

    端口:12223
    服務:【null】
    說明:木馬hack? keylogger開放此端口。

    端口:12345、12346
    服務:【null】
    說明:木馬netbus1.60/1.70、gabanbus開放此端口。

    端口:12361
    服務:【null】
    說明:木馬whack-a-mole開放此端口。

    端口:13223
    服務:powwow
    說 明:powwow是tribal voice的聊天程序。它允許用戶在此端口打開私人聊天的連接。這一程序對于建立連接非常具有攻擊性。它會駐扎在這個tcp端口等回應。造成類似心跳間隔 的連接請求。如果一個撥號用戶從另一個聊天者手中繼承了ip地址就會發生好象有很多不同的人在測試這個端口的情況。這一協議使用opng作為其連接請求的 前4個字節。

    端口:16969
    服務:【null】
    說明:木馬priority開放此端口。

    端口:17027
    服務:conducent
    說明:這是一個外向連接。這是由于公司內部有人安裝了帶有conducent"adbot"的共享軟件。conducent"adbot"是為共享軟件顯示廣告服務的。使用這種服務的一種流行的軟件是pkware。

    端口:19191
    服務:【null】
    說明:木馬藍色火焰開放此端口。

    端口:20000、20001
    服務:【null】
    說明:木馬millennium開放此端口。

    端口:20034
    服務:【null】
    說明:木馬netbus pro開放此端口。

    端口:21554
    服務:【null】
    說明:木馬girlfriend開放此端口。

    端口:22222
    服務:【null】
    說明:木馬prosiak開放此端口。

    端口:23456
    服務:【null】
    說明:木馬evil ftp、ugly ftp開放此端口。

    端口:26274、47262
    服務:【null】
    說明:木馬delta開放此端口。

    端口:27374
    服務:【null】
    說明:木馬subseven 2.1開放此端口。

    端口:30100
    服務:【null】
    說明:木馬netsphere開放此端口。

    端口:30303
    服務:【null】
    說明:木馬socket23開放此端口。

    端口:30999
    服務:【null】
    說明:木馬kuang開放此端口。

    端口:31337、31338
    服務:【null】
    說明:木馬bo(back orifice)開放此端口。另外木馬deepbo也開放31338端口。

    端口:31339
    服務:【null】
    說明:木馬netspy dk開放此端口。

    端口:31666
    服務:【null】
    說明:木馬bowhack開放此端口。

    端口:33333
    服務:【null】
    說明:木馬prosiak開放此端口。

    端口:34324
    服務:【null】
    說明:木馬tiny telnet server、biggluck、tn開放此端口。

    端口:40412
    服務:【null】
    說明:木馬the spy開放此端口。

    端口:40421、40422、40423、40426、
    服務:【null】
    說明:木馬masters paradise開放此端口。

    端口:43210、54321
    服務:【null】
    說明:木馬schoolbus 1.0/2.0開放此端口。

    端口:44445
    服務:【null】
    說明:木馬happypig開放此端口。

    端口:50766
    服務:【null】
    說明:木馬fore開放此端口。

    端口:53001
    服務:【null】
    說明:木馬remote windows shutdown開放此端口。

    端口:65000
    服務:【null】
    說明:木馬devil 1.03開放此端口。


    端口:88
    說明:kerberos krb5。另外tcp的88端口也是這個用途。

    端口:137
    說 明:sql named pipes encryption over other protocols name lookup(其他協議名稱查找上的sql命名管道加密技術)和sql rpc encryption over other protocols name lookup(其他協議名稱查找上的sql rpc加密技術)和wins netbt name service(wins netbt名稱服務)和wins proxy都用這個端口。

    端口:161
    說明:simple network management protocol(smtp)(簡單網絡管理協議)。

    端口:162
    說明:snmp trap(snmp陷阱)

    端口:445
    說明:common internet file system(cifs)(公共internet文件系統)

    端口:464
    說明:kerberos kpasswd(v5)。另外tcp的464端口也是這個用途。

    端口:500
    說明:internet key exchange(ike)(internet密鑰交換)

    端口:1645、1812
    說明:remot authentication dial-in user service(radius)authentication(routing and remote access)(遠程認證撥號用戶服務)

    端口:1646、1813
    說明:radius accounting(routing and remote access)(radius記帳(路由和遠程訪問))

    端口:1701
    說明:layer two tunneling protocol(l2tp)(第2層隧道協議)

    端口:1801、3527
    說明:microsoft message queue server(microsoft消息隊列服務器)。還有tcp的135、1801、2101、2103、2105也是同樣的用途。

    端口:2504
    說明:network load balancing(網絡平衡負荷)
    posted @ 2011-06-20 20:17 ivaneeo 閱讀(432) | 評論 (0)編輯 收藏

     前面系統討論過java類型加載(loading)的問題,在這篇文章中簡要分析一下java類型卸載(unloading)的問題,并簡要分析一下如何解決如何運行時加載newly compiled version的問題。

    【相關規范摘要】
        首先看一下,關于java虛擬機規范中時如何闡述類型卸載(unloading)的:
        A class or interface may be unloaded if and only if its class loader is unreachable. The bootstrap class loader is always reachable; as a result, system classes may never be unloaded.
        Java虛擬機規范中關于類型卸載的內容就這么簡單兩句話,大致意思就是:只有當加載該類型的類加載器實例(非類加載器類型)為unreachable狀態時,當前被加載的類型才被卸載.啟動類加載器實例永遠為reachable狀態,由啟動類加載器加載的類型可能永遠不會被卸載.

        我們再看一下Java語言規范提供的關于類型卸載的更詳細的信息(部分摘錄):
        //摘自JLS 12.7 Unloading of Classes and Interfaces
        1、An implementation of the Java programming language may unload classes.
        2、Class unloading is an optimization that helps reduce memory use. Obviously,the semantics of a program should not depend  on whether and how a system chooses to implement an optimization such as class unloading.
        3、Consequently,whether a class or interface has been unloaded or not should be transparent to a program

        通過以上我們可以得出結論: 類型卸載(unloading)僅僅是作為一種減少內存使用的性能優化措施存在的,具體和虛擬機實現有關,對開發者來說是透明的.

        縱觀java語言規范及其相關的API規范,找不到顯示類型卸載(unloading)的接口, 換句話說:
        1、一個已經加載的類型被卸載的幾率很小至少被卸載的時間是不確定的
        2、一個被特定類加載器實例加載的類型運行時可以認為是無法被更新的

    【類型卸載進一步分析】
         前面提到過,如果想卸載某類型,必須保證加載該類型的類加載器處于unreachable狀態,現在我們再看看有 關unreachable狀態的解釋:
        1、A reachable object is any object that can be accessed in any potential continuing computation from any live thread.
        2、finalizer-reachable: A finalizer-reachable object can be reached from some finalizable object through some chain of references, but not from any live thread. An unreachable object cannot be reached by either means.

        某種程度上講,在一個稍微復雜的java應用中,我們很難準確判斷出一個實例是否處于unreachable狀態,所    以為了更加準確的逼近這個所謂的unreachable狀態,我們下面的測試代碼盡量簡單一點.
        
        【測試場景一】使用自定義類加載器加載, 然后測試將其設置為unreachable的狀態
        說明:
        1、自定義類加載器(為了簡單起見, 這里就假設加載當前工程以外D盤某文件夾的class)
        2、假設目前有一個簡單自定義類型MyClass對應的字節碼存在于D:/classes目錄下
        
    public class MyURLClassLoader extends URLClassLoader {
       public MyURLClassLoader() {
          super(getMyURLs());
       }

       private static URL[] getMyURLs() {
        try {
           return new URL[]{new File ("D:/classes/").toURL()};
        } catch (Exception e) {
           e.printStackTrace();
           return null;
        }
      }
    }

     1 public class Main {
     2     public static void main(String[] args) {
     3       try {
     4          MyURLClassLoader classLoader = new MyURLClassLoader();
     5          Class classLoaded = classLoader.loadClass("MyClass");
     6          System.out.println(classLoaded.getName());
     7
     8          classLoaded = null;
     9          classLoader = null;
    10
    11          System.out.println("開始GC");
    12          System.gc();
    13          System.out.println("GC完成");
    14        } catch (Exception e) {
    15            e.printStackTrace();
    16        }
    17     }
    18 }

            我們增加虛擬機參數-verbose:gc來觀察垃圾收集的情況,對應輸出如下:   
    MyClass
    開始GC
    [Full GC[Unloading class MyClass]
    207K->131K(1984K), 0.0126452 secs]
    GC完成

        【測試場景二】使用系統類加載器加載,但是無法將其設置為unreachable的狀態
          說明:將場景一中的MyClass類型字節碼文件放置到工程的輸出目錄下,以便系統類加載器可以加載
            
     1 public class Main {
     2     public static void main(String[] args) {
     3      try {
     4       Class classLoaded =  ClassLoader.getSystemClassLoader().loadClass(
     5 "MyClass");
     6
     7
     8      System.out.printl(sun.misc.Launcher.getLauncher().getClassLoader());
     9      System.out.println(classLoaded.getClassLoader());
    10      System.out.println(Main.class.getClassLoader());
    11
    12      classLoaded = null;
    13
    14      System.out.println("開始GC");
    15      System.gc();
    16      System.out.println("GC完成");
    17
    18      //判斷當前系統類加載器是否有被引用(是否是unreachable狀態)
    19      System.out.println(Main.class.getClassLoader());
    20     } catch (Exception e) {
    21         e.printStackTrace();
    22     }
    23   }
    24 }
            
            我們增加虛擬機參數-verbose:gc來觀察垃圾收集的情況, 對應輸出如下:
    sun.misc.Launcher$AppClassLoader@197d257
    sun.misc.Launcher$AppClassLoader@197d257
    sun.misc.Launcher$AppClassLoader@197d257
    開始GC
    [Full GC 196K->131K(1984K), 0.0130748 secs]
    GC完成
    sun.misc.Launcher$AppClassLoader@197d257

            由于系統ClassLoader實例(AppClassLoader@197d257">sun.misc.Launcher$AppClassLoader@197d257)加載了很多類型,而且又沒有明確的接口將其設置為null,所以我們無法將加載MyClass類型的系統類加載器實例設置為unreachable狀態,所以通過測試結果我們可以看出,MyClass類型并沒有被卸載.(說明: 像類加載器實例這種較為特殊的對象一般在很多地方被引用, 會在虛擬機中呆比較長的時間)

        【測試場景三】使用擴展類加載器加載, 但是無法將其設置為unreachable的狀態

            說明:將測試場景二中的MyClass類型字節碼文件打包成jar放置到JRE擴展目錄下,以便擴展類加載器可以加載的到。由于標志擴展ClassLoader實例(ExtClassLoader@7259da">sun.misc.Launcher$ExtClassLoader@7259da)加載了很多類型,而且又沒有明確的接口將其設置為null,所以我們無法將加載MyClass類型的系統類加載器實例設置為unreachable狀態,所以通過測試結果我們可以看出,MyClass類型并沒有被卸載.
            
     1 public class Main {
     2      public static void main(String[] args) {
     3        try {
     4          Class classLoaded = ClassLoader.getSystemClassLoader().getParent()
     5 .loadClass("MyClass");
     6
     7          System.out.println(classLoaded.getClassLoader());
     8
     9          classLoaded = null;
    10
    11          System.out.println("開始GC");
    12          System.gc();
    13          System.out.println("GC完成");
    14          //判斷當前標準擴展類加載器是否有被引用(是否是unreachable狀態)
    15          System.out.println(Main.class.getClassLoader().getParent());
    16       } catch (Exception e) {
    17          e.printStackTrace();
    18       }
    19    }
    20 }

            我們增加虛擬機參數-verbose:gc來觀察垃圾收集的情況,對應輸出如下:
    sun.misc.Launcher$ExtClassLoader@7259da
    開始GC
    [Full GC 199K->133K(1984K), 0.0139811 secs]
    GC完成
    sun.misc.Launcher$ExtClassLoader@7259da


        關于啟動類加載器我們就不需再做相關的測試了,jvm規范和JLS中已經有明確的說明了.


        【類型卸載總結】
        通過以上的相關測試(雖然測試的場景較為簡單)我們可以大致這樣概括:
        1、有啟動類加載器加載的類型在整個運行期間是不可能被卸載的(jvm和jls規范).
        2、被系統類加載器和標準擴展類加載器加載的類型在運行期間不太可能被卸載,因為系統類加載器實例或者標準擴展類的實例基本上在整個運行期間總能直接或者間接的訪問的到,其達到unreachable的可能性極小.(當然,在虛擬機快退出的時候可以,因為不管ClassLoader實例或者Class(java.lang.Class)實例也都是在堆中存在,同樣遵循垃圾收集的規則).
        3、被開發者自定義的類加載器實例加載的類型只有在很簡單的上下文環境中才能被卸載,而且一般還要借助于強制調用虛擬機的垃圾收集功能才可以做到.可以預想,稍微復雜點的應用場景中(尤其很多時候,用戶在開發自定義類加載器實例的時候采用緩存的策略以提高系統性能),被加載的類型在運行期間也是幾乎不太可能被卸載的(至少卸載的時間是不確定的).

          綜合以上三點,我們可以默認前面的結論1, 一個已經加載的類型被卸載的幾率很小至少被卸載的時間是不確定的.同時,我們可以看的出來,開發者在開發代碼時候,不應該對虛擬機的類型卸載做任何假設的前提下來實現系統中的特定功能.
        
          【類型更新進一步分析】
        前面已經明確說過,被一個特定類加載器實例加載的特定類型在運行時是無法被更新的.注意這里說的
             是一個特定的類加載器實例,而非一個特定的類加載器類型.
        
            【測試場景四】
            說明:現在要刪除前面已經放在工程輸出目錄下和擴展目錄下的對應的MyClass類型對應的字節碼
            
     1 public class Main {
     2      public static void main(String[] args) {
     3        try {
     4          MyURLClassLoader classLoader = new MyURLClassLoader();
     5          Class classLoaded1 = classLoader.loadClass("MyClass");
     6          Class classLoaded2 = classLoader.loadClass("MyClass");
     7          //判斷兩次加載classloader實例是否相同
     8           System.out.println(classLoaded1.getClassLoader() == classLoaded2.getClassLoader());
     9
    10         //判斷兩個Class實例是否相同
    11           System.out.println(classLoaded1 == classLoaded2);
    12       } catch (Exception e) {
    13          e.printStackTrace();
    14       }
    15    }
    16 }
            輸出如下:
            true
            true

            通過結果我們可以看出來,兩次加載獲取到的兩個Class類型實例是相同的.那是不是確實是我們的自定義
           類加載器真正意義上加載了兩次呢(即從獲取class字節碼到定義class類型…整個過程呢)?
          通過對java.lang.ClassLoader的loadClass(String name,boolean resolve)方法進行調試,我們可以看出來,第二
          次  加載并不是真正意義上的加載,而是直接返回了上次加載的結果.

           說明:為了調試方便, 在Class classLoaded2 = classLoader.loadClass("MyClass");行設置斷點,然后單步跳入, 可以看到第二次加載請求返回的結果直接是上次加載的Class實例. 調試過程中的截圖? 最好能自己調試一下).
          
         
            【測試場景五】同一個類加載器實例重復加載同一類型
            說明:首先要對已有的用戶自定義類加載器做一定的修改,要覆蓋已有的類加載邏輯, MyURLClassLoader.java類簡要修改如下:重新運行測試場景四中的測試代碼
          
     1 public class MyURLClassLoader extends URLClassLoader {
     2     //省略部分的代碼和前面相同,只是新增如下覆蓋方法
     3     /*
     4     * 覆蓋默認的加載邏輯,如果是D:/classes/下的類型每次強制重新完整加載
     5     *
     6     * @see java.lang.ClassLoader#loadClass(java.lang.String)
     7     */
     8     @Override
     9     public Class<?> loadClass(String name) throws ClassNotFoundException {
    10      try {
    11        //首先調用系統類加載器加載
    12         Class c = ClassLoader.getSystemClassLoader().loadClass(name);
    13        return c;
    14      } catch (ClassNotFoundException e) {
    15       // 如果系統類加載器及其父類加載器加載不上,則調用自身邏輯來加載D:/classes/下的類型
    16          return this.findClass(name);
    17      }
    18   }
    19 }
    說明: this.findClass(name)會進一步調用父類URLClassLoader中的對應方法,其中涉及到了defineClass(String name)的調用,所以說現在類加載器MyURLClassLoader會針對D:/classes/目錄下的類型進行真正意義上的強制加載并定義對應的類型信息.

            測試輸出如下:
            Exception in thread "main" java.lang.LinkageError: duplicate class definition: MyClass
           at java.lang.ClassLoader.defineClass1(Native Method)
           at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
           at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
           at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
           at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
           at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
           at java.security.AccessController.doPrivileged(Native Method)
           at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
           at MyURLClassLoader.loadClass(MyURLClassLoader.java:51)
           at Main.main(Main.java:27)
          
           結論:如果同一個類加載器實例重復強制加載(含有定義類型defineClass動作)相同類型,會引起java.lang.LinkageError: duplicate class definition.
        
           【測試場景六】同一個加載器類型的不同實例重復加載同一類型
           
     1 public class Main {
     2     public static void main(String[] args) {
     3       try {
     4         MyURLClassLoader classLoader1 = new MyURLClassLoader();
     5         Class classLoaded1 = classLoader1.loadClass("MyClass");
     6         MyURLClassLoader classLoader2 = new MyURLClassLoader();
     7         Class classLoaded2 = classLoader2.loadClass("MyClass");
     8
     9         //判斷兩個Class實例是否相同
    10          System.out.println(classLoaded1 == classLoaded2);
    11       } catch (Exception e) {
    12          e.printStackTrace();
    13       }
    14    }
    15 }

          測試對應的輸出如下:
          false
         
        
            【類型更新總結】   
         由不同類加載器實例重復強制加載(含有定義類型defineClass動作)同一類型不會引起java.lang.LinkageError錯誤, 但是加載結果對應的Class類型實例是不同的,即實際上是不同的類型(雖然包名+類名相同). 如果強制轉化使用,會引起ClassCastException.(說明: 頭一段時間那篇文章中解釋過,為什么不同類加載器加載同名類型實際得到的結果其實是不同類型, 在JVM中一個類用其全名和一個加載類ClassLoader的實例作為唯一標識,不同類加載器加載的類將被置于不同的命名空間).


            應用場景:我們在開發的時候可能會遇到這樣的需求,就是要動態加載某指定類型class文件的不同版本,以便能動態更新對應功能.
             建議:
            1. 不要寄希望于等待指定類型的以前版本被卸載,卸載行為對java開發人員透明的.
            2. 比較可靠的做法是,每次創建特定類加載器的新實例來加載指定類型的不同版本,這種使用場景下,一般就要犧牲緩存特定類型的類加載器實例以帶來性能優化的策略了.對于指定類型已經被加載的版本, 會在適當時機達到unreachable狀態,被unload并垃圾回收.每次使用完類加載器特定實例后(確定不需要再使用時), 將其顯示賦為null, 這樣可能會比較快的達到jvm 規范中所說的類加載器實例unreachable狀態, 增大已經不再使用的類型版本被盡快卸載的機會.
            3. 不得不提的是,每次用新的類加載器實例去加載指定類型的指定版本,確實會帶來一定的內存消耗,一般類加載器實例會在內存中保留比較長的時間. 在bea開發者網站上找到一篇相關的文章(有專門分析ClassLoader的部分):http://dev2dev.bea.com/pub/a/2005/06/memory_leaks.html

               寫的過程中參考了jvm規范和jls, 并參考了sun公司官方網站上的一些bug的分析文檔。

               歡迎大家批評指正!


    本博客中的所有文章、隨筆除了標題中含有引用或者轉載字樣的,其他均為原創。轉載請注明出處,謝謝!
    posted @ 2011-06-16 20:05 ivaneeo 閱讀(348) | 評論 (0)編輯 收藏

    啟動集群中所有的regionserver
    ./hbase-daemons.sh start regionserver
    啟動某個regionserver
    ./hbase-daemon.sh start regionserver
    posted @ 2011-06-16 12:10 ivaneeo 閱讀(1516) | 評論 (0)編輯 收藏

    做了幾天工程,對HBase中的表操作熟悉了一下。下面總結一下常用的表操作和容易出錯的幾個方面。當然主要來源于大牛們的文章。我在前人的基礎上稍作解釋。

    1.連接HBase中的表testtable,用戶名:root,密碼:root

    public void ConnectHBaseTable()
     {
      Configuration conf = new Configuration();       
            conf.set("hadoop.job.ugi", "root,root");      
      HBaseConfiguration config = new HBaseConfiguration();
      try
      {
       table = new HTable(config, "testtable");
      }catch(Exception e){e.printStackTrace();}
     }

    2.根據行名name獲得一行數據,存入Result.注意HBase中的表數據是字節存儲的。

       下面的例子表示獲得行名為name的行的famA列族col1列的數據。

          String rowId = "name";
          Get get = new Get(rowId);
          Result result = hTable.get(get);
          byte[] value = result.getValue(famA, col1);
          System.out.println(Bytes.toString(value));

    3.向表中存數據

          下面的例子表示寫入一行。行名為abcd,famA列族col1列的數據為"hello world!"。

          byte[] rowId = Bytes.toBytes("abcd");
          byte[] famA = Bytes.toBytes("famA");
          byte[] col1 = Bytes.toBytes("col1");
          Put put = new Put(rowId).
             add(famA, col1, Bytes.toBytes("hello world!"));
          hTable.put(put);
         

    4.掃描的用法(scan):便于獲得自己需要的數據,相當于SQL查詢。

          byte[] famA = Bytes.toBytes("famA");
          byte[] col1 = Bytes.toBytes("col1");  

          HTable hTable = new HTable("test");  

          //表示要查詢的行名是從a開始,到z結束。
          Scan scan = new Scan(Bytes.toBytes("a"), Bytes.toBytes("z"));
         

          //用scan.setStartRow(Bytes.toBytes(""));設置起始行

          //用scan.setStopRow(Bytes.toBytes(""));設置終止行

          //表示查詢famA族col1列

          scan.addColumn(famA, col1);  

          //注意,下面是filter的寫法。相當于SQL的where子句

          //表示famA族col1列的數據等于"hello world!"
          
    SingleColumnValueFilter singleColumnValueFilterA = new SingleColumnValueFilter(
               famA, col1, CompareOp.EQUAL, Bytes.toBytes("hello world!"));
          singleColumnValueFilterA.setFilterIfMissing(true);  

          //表示famA族col1列的數據等于"hello hbase!"
          
    SingleColumnValueFilter singleColumnValueFilterB = new SingleColumnValueFilter(
               famA, col1, CompareOp.EQUAL, Bytes.toBytes("hello hbase!"));
          singleColumnValueFilterB.setFilterIfMissing(true);  
          

          //表示famA族col1列的數據是兩者中的一個
          FilterList filter = new FilterList(Operator.MUST_PASS_ONE, Arrays
               .asList((Filter) singleColumnValueFilterA,
                    singleColumnValueFilterB));  

          scan.setFilter(filter);  

          ResultScanner scanner = hTable.getScanner(scan);  
          //遍歷每個數據
          for (Result result : scanner) {
             System.out.println(Bytes.toString(result.getValue(famA, col1)));
          }

    5.上面的代碼容易出錯的地方在于,需要導入HBase的類所在的包。導入時需要選擇包,由于類可能出現在HBase的各個子包中,所以要選擇好,下面列出常用的包。盡量用HBase的包

    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.client.Get;
    import org.apache.hadoop.hbase.client.HTable;
    import org.apache.hadoop.hbase.client.Put;
    import org.apache.hadoop.hbase.client.Result;
    import org.apache.hadoop.hbase.client.ResultScanner;
    import org.apache.hadoop.hbase.client.Scan;
    import org.apache.hadoop.hbase.filter.Filter;
    import org.apache.hadoop.hbase.filter.FilterList;
    import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
    import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
    import org.apache.hadoop.hbase.filter.FilterList.Operator;
    import org.apache.hadoop.hbase.util.Bytes;

    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Date;

    6.下面列出HBase常用的操作

    (1)時間戳到時間的轉換.單一的時間戳無法給出直觀的解釋。

    public String GetTimeByStamp(String timestamp)
     {

      long datatime= Long.parseLong(timestamp); 
         Date date=new Date(datatime);   
         SimpleDateFormat   format=new   SimpleDateFormat("yyyy-MM-dd HH:MM:ss");   
         String timeresult=format.format(date);
         System.out.println("Time : "+timeresult);
         return timeresult;
     }

    (2)時間到時間戳的轉換。注意時間是字符串格式。字符串與時間的相互轉換,此不贅述

    public String GetStampByTime(String time)
     {
      String Stamp="";
      SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      Date date;
      try
      {
       date=sdf.parse(time);
       Stamp=date.getTime()+"000";
       System.out.println(Stamp);
      }catch(Exception e){e.printStackTrace();}
      return Stamp;
     }

    上面就是我的一點心得。以后碰到什么問題,再來解決。

    參考文獻:http://www.nearinfinity.com/blogs/aaron_mccurry/using_hbase-dsl.html

    posted @ 2011-06-15 17:17 ivaneeo 閱讀(503) | 評論 (0)編輯 收藏

    官方Book Performance Tuning部分章節沒有按配置項進行索引,不能達到快速查閱的效果。所以我以配置項驅動,重新整理了原文,并補充一些自己的理解,如有錯誤,歡迎指正。

    配置優化

    zookeeper.session.timeout
    默認值:3分鐘(180000ms)
    說明:RegionServer與Zookeeper間的連接超時時間。當超時時間到后,ReigonServer會 被Zookeeper從RS集群清單中移除,HMaster收到移除通知后,會對這臺server負責的regions重新balance,讓其他存活的 RegionServer接管.
    調優
    這個timeout決定了RegionServer是否能夠及時的failover。設置成1分鐘或更低,可以減少因等待超時而被延長的failover時間。
    不過需要注意的是,對于一些Online應用,RegionServer的宕機到恢復時間本身就很短的(網絡閃斷,crash等故障,運維可快速介入), 如果調低timeout時間,會得不償失。因為當ReigonServer被正式從RS集群中移除時,HMaster就開始做balance了,當故障的 RS快速恢復后,這個balance動作是毫無意義的,反而會使負載不均勻,給RS帶來更多負擔。

    hbase.regionserver.handler.count
    默認值:10
    說明:RegionServer的請求處理IO線程數。
    調優
    這個參數的調優與內存息息相關。
    較少的IO線程,適用于處理單次請求內存消耗較高的Big PUT場景(大容量單次PUT或設置了較大cache的scan,均屬于Big PUT)或ReigonServer的內存比較緊張的場景。
    較多的IO線程,適用于單次請求內存消耗低,TPS要求非常高的場景。
    這里需要注意的是如果server的region數量很少,大量的請求都落在一個region上,因快速充滿memstore觸發flush導致的讀寫鎖會影響全局TPS,不是IO線程數越高越好。
    壓測時,開啟Enabling RPC-level logging,可以同時監控每次請求的內存消耗和GC的狀況,最后通過多次壓測結果來合理調節IO線程數。
    這里是一個案例 Hadoop and HBase Optimization for Read Intensive Search Applications,作者在SSD的機器上設置IO線程數為100,僅供參考。

    hbase.hregion.max.filesize
    默認值:256M
    說明:在當前ReigonServer上單個Reigon的大小,單個Region超過指定值時,這個Region會被自動split成更小的region。
    調優
    小region對split和compaction友好,因為拆分region或compact小region里的storefile速度很快,內存占用低。缺點是split和compaction會很頻繁。
    特別是數量較多的小region不停地split, compaction,會使響應時間波動很大,region數量太多不僅給管理上帶來麻煩,甚至引發一些Hbase的bug。
    一般512以下的都算小region。

    大region,則不太適合經常split和compaction,因為做一次compact和split會產生較長時間的停頓,對應用的讀寫性能沖擊非常大。此外,大region意味著較大的storefile,compaction時對內存也是一個挑戰。
    當然,大region還是有其用武之地,你只要在某個訪問量低峰的時間點統一做compact和split,大region就可以發揮優勢了,畢竟它能保證絕大多數時間平穩的讀寫性能。

    既然split和compaction如此影響性能,有沒有辦法去掉?
    compaction是無法避免的,split倒是可以從自動調整為手動。
    只要通過將這個參數值調大到某個很難達到的值,比如100G,就可以間接禁用自動split(RegionServer不會對未到達100G的region做split)。
    再配合RegionSplitter這個工具,在需要split時,手動split。
    手動split在靈活性和穩定性上比起自動split要高很多,相反,管理成本增加不多,比較推薦online實時系統使用。

    內存方面,小region在設置memstore的大小值上比較靈活,大region則過大過小都不行,過大會導致flush時app的IO wait增高,過小則因store file過多讀性能降低。

    hbase.regionserver.global.memstore.upperLimit/lowerLimit

    默認值:0.4/0.35
    upperlimit說明:hbase.hregion.memstore.flush.size 這個參數的作用是 當單個memstore達到指定值時,flush該memstore。但是,一臺ReigonServer可能有成百上千個memstore,每個 memstore也許未達到flush.size,jvm的heap就不夠用了。該參數就是為了限制memstores占用的總內存。
    當ReigonServer內所有的memstore所占用的內存綜合達到heap的40%時,HBase會強制block所有的更新并flush這些memstore以釋放所有memstore占用的內存。
    lowerLimit說明: 同upperLimit,只不過當全局memstore的內存達到35%時,它不會flush所有的memstore,它會找一些內存占用較大的 memstore,個別flush,當然更新還是會被block。lowerLimit算是一個在全局flush前的補救措施。可以想象一下,如果 memstore需要在一段時間內全部flush,且這段時間內無法接受寫請求,對HBase集群的性能影響是很大的。
    調優:這是一個Heap內存保護參數,默認值已經能適用大多數場景。它的調整一般是為了配合某些專屬優化,比如讀密集型應用,將讀緩存開大,降低該值,騰出更多內存給其他模塊使用。
    這個參數會給使用者帶來什么影響?
    比如,10G內存,100個region,每個memstore 64M,假設每個region只有一個memstore,那么當100個memstore平均占用到50%左右時,就會達到lowerLimit的限制。 假設此時,其他memstore同樣有很多的寫請求進來。在那些大的region未flush完,就可能又超過了upperlimit,則所有 region都會被block,開始觸發全局flush。

    hfile.block.cache.size

    默認值:0.2
    說明:storefile的讀緩存占用Heap的大小百分比,0.2表示20%。該值直接影響數據讀的性能。
    調優:當然是越大越好,如果讀比寫少,開到0.4-0.5也沒問題。如果讀寫較均衡,0.3左右。如果寫比讀多,果斷 默認吧。設置這個值的時候,你同時要參考 hbase.regionserver.global.memstore.upperLimit ,該值是 memstore占heap的最大百分比,兩個參數一個影響讀,一個影響寫。如果兩值加起來超過80-90%,會有OOM的風險,謹慎設置。

    hbase.hstore.blockingStoreFiles

    默認值:7
    說明:在compaction時,如果一個Store(Coulmn Family)內有超過7個storefile需要合并,則block所有的寫請求,進行flush,限制storefile數量增長過快。
    調優:block請求會影響當前region的讀寫性能,將值設為單個region可以支撐的最大store file數量會是個不錯的選擇。最大storefile數量可通過region size/memstore size來計算。如果你將region size設為無限大,那么你需要預估一個region可能產生的最大storefile數。

    hbase.hregion.memstore.block.multiplier

    默認值:2
    說明:當一個region里的memstore超過單個memstore.size兩倍的大小時,block該 region的所有請求,進行flush,釋放內存。雖然我們設置了memstore的總大小,比如64M,但想象一下,在最后63.9M的時候,我 Put了一個100M的數據或寫請求量暴增,最后一秒鐘put了1萬次,此時memstore的大小會瞬間暴漲到超過預期的memstore.size。 這個參數的作用是當memstore的大小增至超過memstore.size時,block所有請求,遏制風險進一步擴大。
    調優: 這個參數的默認值還是比較靠譜的。如果你預估你的正常應用場景(不包括異常)不會出現突發寫或寫的量可控,那么保持默認值即可。如果正常情況下,你的寫量 就會經常暴增,那么你應該調大這個倍數并調整其他參數值,比如hfile.block.cache.size和 hbase.regionserver.global.memstore.upperLimit/lowerLimit,以預留更多內存,防止HBase server OOM。

    其他

    啟用LZO壓縮
    LZO對比Hbase默認的GZip,前者性能較高,后者壓縮比較高,具體參見 Using LZO Compression對于想提高HBase讀寫性能的開發者,采用LZO是比較好的選擇。對于非常在乎存儲空間的開發者,則建議保持默認。

    不要在一張表里定義太多的Column Family

    Hbase目前不能良好的處理超過2-3個CF的表。因為某個CF在flush發生時,它鄰近的CF也會因關聯效應被觸發flush,最終導致系統產生很多IO。

    批量導入

    在批量導入數據到Hbase前,你可以通過預先創建region,來平衡數據的負載。詳見 Table Creation: Pre-Creating Regions

    Hbase客戶端優化

    AutoFlush

    HTable的setAutoFlush設為false,可以支持客戶端批量更新。即當Put填滿客戶端flush緩存時,才發送到服務端。
    默認是true。

    Scan Caching

    scanner一次緩存多少數據來scan(從服務端一次抓多少數據回來scan)。
    默認值是 1,一次只取一條。

    Scan Attribute Selection

    scan時建議指定需要的Column Family,減少通信量,否則scan默認會返回整個row的所有數據(所有Coulmn Family)。

    Close ResultScanners

    通過scan取完數據后,記得要關閉ResultScanner,否則RegionServer可能會出現問題。

    Optimal Loading of Row Keys

    當你scan一張表的時候,返回結果只需要row key(不需要CF, qualifier,values,timestaps)時,你可以在scan實例中添加一個filterList,并設置 MUST_PASS_ALL操作,filterList中add FirstKeyOnlyFilterKeyOnlyFilter。這樣可以減少網絡通信量。

    Turn off WAL on Puts

    當Put某些非重要數據時,你可以設置writeToWAL(false),來進一步提高寫性能。writeToWAL(false)會在Put時放棄寫WAL log。風險是,當RegionServer宕機時,可能你剛才Put的那些數據會丟失,且無法恢復。

    啟用Bloom Filter

    Bloom Filter通過空間換時間,提高讀操作性能。

    轉載請注明原文鏈接:http://kenwublog.com/hbase-performance-tuning

    posted @ 2011-06-15 13:39 ivaneeo 閱讀(2798) | 評論 (0)編輯 收藏

    We recently set up HBase and HBase-trx (from https://github.com/hbase-trx) to use multiple-column indexes with this code.  After you compile it, just copy the jar and the hbase-trx jar into your hbase’s lib folder and you should be good to to!

    When you create a composite index, you can see the metadata for the index by looking at the table description.  One of the properties will read “INDEXES =>” followed by index names and ‘family:qualifier’ style column names in the index.

    KeyGeneratorFactory:

    package com.ir.store.hbase.indexes;

    import java.util.List;

    import org.apache.hadoop.hbase.client.tableindexed.IndexKeyGenerator;

    public class KeyGeneratorFactory {

    public static IndexKeyGenerator getInstance(List columns) {
    return new HBaseIndexKeyGenerator(columns);
    }
    }

    HBaseIndexKeyGenerator:

    package com.ir.store.hbase.indexes;

    import java.io.DataInput;
    import java.io.DataOutput;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import org.apache.hadoop.hbase.client.tableindexed.IndexKeyGenerator;
    import org.apache.hadoop.hbase.util.Bytes;

    public class HBaseIndexKeyGenerator extends Object implements IndexKeyGenerator {
    public static byte[] KEYSEPERATOR = "~;?".getBytes();

    private int columnCount;
    private List columnNames = new ArrayList();

    public HBaseIndexKeyGenerator(List memberColumns) {
    // For new key generators
    columnNames = memberColumns;
    columnCount = memberColumns.size();
    }

    public HBaseIndexKeyGenerator() {
    // Hollow constructor for deserializing -- should call readFields shortly
    columnCount = 0;
    }

    public void readFields(DataInput binaryInput) throws IOException {
    columnCount = binaryInput.readInt();
    for (int currentColumn = 0; currentColumn < columnCount; currentColumn++)
    columnNames.add(Bytes.readByteArray(binaryInput));
    }

    public void write(DataOutput binaryOutput) throws IOException {
    binaryOutput.writeInt(columnCount);
    for (byte[] columnName : columnNames)
    Bytes.writeByteArray(binaryOutput, columnName);
    }

    public byte[] createIndexKey(byte[] baseRowIdentifier, Map baseRowData) {
    byte[] indexRowIdentifier = null;
    for (byte[] columnName: columnNames) {
    if (indexRowIdentifier == null)
    indexRowIdentifier = baseRowData.get(columnName);
    else indexRowIdentifier = Bytes.add(indexRowIdentifier, HBaseIndexKeyGenerator.KEYSEPERATOR, baseRowData.get(columnName));
    }
    if (baseRowIdentifier != null)
    return Bytes.add(indexRowIdentifier, HBaseIndexKeyGenerator.KEYSEPERATOR, baseRowIdentifier);
    return indexRowIdentifier;
    }
    }
    posted @ 2011-06-11 16:21 ivaneeo 閱讀(404) | 評論 (0)編輯 收藏

    對于Bigtable類型的分布式數據庫應用來說,用戶往往會對其性能狀況有極大的興趣,這其中又對實時數據插入性能更為關注。HBase作為Bigtable的一個實現,在這方面的性能會如何呢?這就需要通過測試數據來說話了。

    數據插入性能測試的設計場景是這樣的,取隨機值的Rowkey長度為2000字節,固定值的Value長度為4000字節,由于單行Row插入速度太快,系統統計精度不夠,所以將插入500行Row做一次耗時統計。

    這里要對HBase的特點做個說明,首先是Rowkey值為何取隨機數,這是因為HBase是對Rowkey進行排序的,隨機Rowkey將被分配到不同的region上,這樣才能發揮出分布式數據庫的性能優點。而Value對于HBase來說不會進行任何解析,其數據是否變化,對性能是不應該有任何影響的。同時為了簡單起見,所有的數據都將只插入到一個表格的同一個Column中。

    在測試之初,需要對集群進行調優,關閉可能大量耗費內存、帶寬以及CPU的服務,例如Apache的Http服務。保持集群的寧靜度。此外,為了保證測試不受干擾,Hbase的集群系統需要被獨立,以保證不與HDFS所在的Hadoop集群有所交叉。

    那么做好一切準備,就開始進行數據灌入,客戶端從Zookeeper上查詢到Regionserver的地址后,開始源源不斷的向Hbase的Regionserver上喂入Row。

    這里,我寫了一個通過JFreeChart來實時生成圖片的程序,每3分鐘,喂數據的客戶端會將獲取到的耗時統計打印在一張十字坐標圖中,這些圖又被保存在制定的web站點中,并通過http服務展示出來。在通過長時間不間斷的測試后,我得到了如下圖形:

    這個圖形非常有特點,好似一條直線上,每隔一段時間就會泛起一個波浪,且兩個高峰之間必有一個較矮的波浪。高峰的間隔則呈現出越來越大的趨勢。而較矮的波浪恰好處于兩高峰的中間位置。

    為了解釋這個現象,我對HDFS上Hbase所在的主目錄下文件,以及被插入表格的region情況進行了實時監控,以期發現這些波浪上發生了什么事情。

    回溯到客戶端喂入數據的開始階段,創建表格,在HDFS上便被創建了一個與表格同名的目錄,該目錄下將出現第一個region,region中會以family名創建一個目錄,這個目錄下才存在記錄具體數據的文件。同時在該表表名目錄下,還會生成一個“compaction.dir”目錄,該目錄將在family名目錄下region文件超過指定數目時用于合并region。

    當第一個region目錄出現的時候,內存中最初被寫入的數據將被保存到這個文件中,這個間隔是由選項“hbase.hregion.memstore.flush.size”決定的,默認是64MB,該region所在的Regionserver的內存中一旦有超過64MB的數據的時候,就將被寫入到region文件中。這個文件將不斷增殖,直到超過由“hbase.hregion.max.filesize”決定的文件大小時(默認是256MB,此時加上內存刷入的數據,實際最大可能到256+64M),該region將被執行split,立即被一切為二,其過程是在該目錄下創建一個名為“.splits”的目錄作為標記,然后由Regionserver將文件信息讀取進來,分別寫入到兩個新的region目錄中,最后再將老的region刪除。這里的標記目錄“.splits”將避免在split過程中發生其他操作,起到類似于多線程安全的鎖功能。在新的region中,從老的region中切分出的數據獨立為一個文件并不再接受新的數據(該文件大小超過了64M,最大可達到(256+64)/2=160MB),內存中新的數據將被保存到一個重新創建的文件中,該文件大小將為64MB。內存每刷新一次,region所在的目錄下就將增加一個64M的文件,直到總文件數超過由“hbase.hstore.compactionThreshold”指定的數量時(默認為3),compaction過程就將被觸發了。在上述值為3時,此時該region目錄下,實際文件數只有兩個,還有額外的一個正處于內存中將要被刷入到磁盤的過程中。Compaction過程是Hbase的一個大動作,Hbase不僅要將這些文件轉移到“compaction.dir”目錄進行壓縮,而且在壓縮后的文件超過256MB時,還必須立即進行split動作。這一系列行為在HDFS上可謂是翻山倒海,影響頗大。待Compaction結束之后,后續的split依然會持續進行一小段時間,直到所有的region都被切割分配完畢,Hbase才會恢復平靜并等待下一次數據從內存寫入到HDFS的到來。

    理解了上述過程,則必然對HBase的數據插入性能為何是上圖所示的曲線的原因一目了然。與X軸幾乎平行的直線,表明數據正在被寫入HBase的Regionserver所在機器的內存中。而較低的波峰意味著Regionserver正在將內存寫入到HDFS上,較高的波峰意味著Regionserver不僅正在將內存刷入到HDFS,而且還在執行Compaction和Split兩種操作。如果調整“hbase.hstore.compactionThreshold”的值為一個較大的數量,例如改成5,可以預見,在每兩個高峰之間必然會等間隔的出現三次較低的波峰,并可預見到,高峰的高度將遠超過上述值為3時的高峰高度(因為Compaction的工作更為艱巨)。由于region數量由少到多,而我們插入的Row的Rowkey是隨機的,因此每一個region中的數據都會均勻的增加,同一段時間插入的數據將被分布到越來越多的region上,因此波峰之間的間隔時間也將會越來越長。

    再次理解上述論述,我們可以推斷出Hbase的數據插入性能實際上應該被分為三種情況,即直線狀態、低峰狀態和高峰狀態。在這三種情況下得到的性能數據才是最終Hbase數據插入性能的真實描述。那么提供給用戶的數據該是采取哪一個呢?我認為直線狀態由于其所占時間會較長,尤其在用戶寫入數據的速度也許并不是那么快的情況下,所以這個狀態下得到的性能數據結果更應該提供給用戶。

    posted @ 2011-06-10 23:33 ivaneeo 閱讀(1602) | 評論 (1)編輯 收藏

    HBase的寫效率還是很高的,但其隨機讀取效率并不高

    可以采取一些優化措施來提高其性能,如:

    1. 啟用lzo壓縮,見這里

    2. 增大hbase.regionserver.handler.count數為100

    3. 增大hfile.block.cache.size為0.4,提高cache大小

    4. 增大hbase.hstore.blockingStoreFiles為15

    5. 啟用BloomFilter,在HBase0,89中可以設置

    6.Put時可以設置setAutoFlush為false,到一定數目后再flushCommits

     

    在14個Region Server的集群上,新建立一個lzo壓縮表

    測試的Put和Get的性能如下:

    1. Put數據:

    單線程灌入1.4億數據,共花費50分鐘,每秒能達到4萬個,這個性能確實很好了,不過插入的value比較小,只有不到幾十個字節

    多線程put,沒有測試,因為單線程的效率已經相當高了

    2. Get數據:

    在沒有任何Block Cache,而且是Random Read的情況:

    單線程平均每秒只能到250個左右

    6個線程平均每秒能達到1100個左右

    16個線程平均每秒能達到2500個左右

    有BlockCache(曾經get過對應的row,而且還在cache中)的情況:

    單線程平均每秒能到3600個左右

    6個線程平均每秒能達到1.2萬個左右

    16個線程平均每秒能達到2.5萬個左右

    posted @ 2011-06-10 23:14 ivaneeo 閱讀(1200) | 評論 (0)編輯 收藏

    僅列出標題
    共67頁: First 上一頁 12 13 14 15 16 17 18 19 20 下一頁 Last 
    主站蜘蛛池模板: 久久青青草原亚洲av无码app| 亚洲熟妇无码AV| **aaaaa毛片免费| 亚洲精品9999久久久久无码| 亚洲成人影院在线观看| 久久久久久毛片免费播放| 亚洲成人激情小说| 国产成人A人亚洲精品无码| 中文字幕无码视频手机免费看 | 久久亚洲综合色一区二区三区| 99热免费在线观看| 国产亚洲精彩视频| 亚洲高清资源在线观看| 亚洲国产精品无码久久青草| 精品国产污污免费网站aⅴ | 精品国产免费一区二区三区香蕉| 67194在线午夜亚洲| 亚洲色婷婷六月亚洲婷婷6月| 少妇高潮太爽了在线观看免费| www在线观看免费视频| 亚洲国产成人久久三区| 国产亚洲av片在线观看18女人| 最近2019中文字幕mv免费看| 99视频有精品视频免费观看| 四虎成人精品国产永久免费无码| 亚洲精品视频久久| 亚洲男同帅GAY片在线观看| 青草草在线视频永久免费| 日韩av无码久久精品免费| 免费中文字幕视频| 亚洲日本VA午夜在线电影| 亚洲自偷自拍另类图片二区| 亚洲一区无码精品色| 国产精品酒店视频免费看| 在线看片韩国免费人成视频| 国产午夜无码精品免费看动漫| 特级毛片全部免费播放| 亚洲色欲色欱wwW在线| 亚洲天堂电影在线观看| 亚洲av激情无码专区在线播放| 国产亚洲精品无码专区|