HBase Shellは、HBaseを操作する対話型ツール。
(OracleのSQL*Plus、JavaDBのij、PostgreSQLのpsqlのようなもの)
HBase0.89で、HBase0.20から機能が増強された。
|
|
(Windowsの場合、Cygwin(bash)から)以下のコマンドでHBase Sehllを起動する。
$ /usr/local/hbase-0.89/bin/hbase shell
--helpを付けるとコマンドのオプションが表示される。
$ /usr/local/hbase-0.89/bin/hbase shell --help HBase Shell command-line options: format Formatter for outputting results: console | html. Default: console -d | --debug Set DEBUG log levels.
なお、HBase ShellはJRubyで書かれているらしい。(HBASE_HOME/bin/hirb.rb)
(なのでJRubyの文を実行することが出来る)
0.89ではformat-widthというオプションは無くなったっぽい。
HBase Shellからhelpコマンドを打ち込むとHBase Shellのコマンド一覧が表示される。
hbase(main):001:0> help
0.89では、一遍に全てのヘルプが表示されるのではなく、グループ名(コマンドの分類)やコマンド名そのものを指定できるようになった。
hbase(main):002:0> help 'ddl' hbase(main):003:0> help 'get'
グループ名 | 分類 | コマンド名 | 引数 | 概要 | ver | RDBのSQL相当 | 更新日 |
---|---|---|---|---|---|---|---|
HBase Shell | exit | HBase Shellを終了する。 | |||||
help | 0-1 | ヘルプを表示する。 | |||||
general | 一般 | version | HBaseのバージョンを表示する。 | ||||
status | 0-1 | クラスターの状態を表示する。 | |||||
ddl | テーブル定義 | list | 0-1 | テーブル一覧を表示する。 | (Oracle)user_tables | ||
exists | 1 | テーブルの存在有無を表示する。 | |||||
create | 1- | テーブルを作成する。 | create table | ||||
drop | 1 | テーブルを削除する。 | drop table | ||||
disable | 1 | テーブルを使用不可に変更する。 | |||||
enable | 1 | テーブルを使用可能に変更する。 | |||||
describe | 1 | テーブルの定義を表示する。 | (Oracle)desc | ||||
alter | 2 | 列ファミリーの定義を変更する。 | alter | ||||
dml | データ表示 | scan | 1-2 | テーブルのデータ(セル)を全て表示する。 | select * | ||
count | 1-2 | テーブルのレコード数(ROWの数)を表示する。 | select count(*) | ||||
get | 2-3 | セルの内容を表示する。 | select | ||||
get_counter | 3 | long型のセルの内容を表示する。 | 0.89 | ||||
データ更新 | put | 4-5 | セルの値をセットする。 | insert/update | |||
incr | 3-4 | セルの値を加算する。 | update | 2010-07-12 | |||
delete | 3-4 | セル(テーブルの値)の最新履歴を削除する。 | update | ||||
deleteall | 2-4 | セル(テーブルの値)の全履歴を削除する。 | delete | ||||
truncate | 1 | テーブルを再作成(データをクリア)する。 | truncate table | ||||
tools | クラスター | tools | HBase外部ツール?(拡張コマンド?)の一覧を表示する。 「 help 'tools' 」と同じ。 |
||||
shutdown | クラスターをシャットダウンする。 | ||||||
disable_region enable_region close_region |
1 1 1-2 |
リージョンを操作する。 引数にはリージョン名を指定する。 |
0.89 | ||||
compact major_compact |
リージョンのコンパクション(圧縮)を行う。 | 0.89 | |||||
flush | 1 | リージョンのフラッシュを行う。 引数にはテーブル名かリージョン名を指定する。 |
0.89 | ||||
split | テーブル・リージョンの分割を行う。 | 0.89 | |||||
zk | ZooKeeperのコマンドを実行する。 「 zk 'help' 」でzkのコマンド一覧が見られる。 |
0.89 | |||||
zk_dump | ZooKeeperによる、HBaseクラスターの状態を表示する。 | 0.89 |
また、HBase ShellはJRubyで動いているので、JRubyの文を実行することが出来る。
テーブル一覧を表示するコマンド。
→Java APIのlistTables()
hbase(main):001:0> list TABLE TEST_TYPE student 2 row(s) in 0.0160 seconds
テーブルの存在有無を表示するコマンド。
hbase(main):002:0> exists 'TEST_TYPE' Table TEST_TYPE does exist 1 row(s) in 0.0000 seconds
テーブルが存在すれば「does exist」、存在しなければ「does not exist」と表示される。
(0.20ではテーブルが存在すればtrue、存在しなければfalseが表示されていた)
テーブルを作成するコマンド。
→Java APIのcreateTable()
hbase(main):014:0> create 'test2','data1','data2' 0 row(s) in 0.1400 seconds
hbase(main):015:0> create 'test2', {NAME => 'data1'}, {NAME => 'data2'}
0.20ではテーブル名のみを指定する(列ファミリーが1個も無いテーブルを作成する)ことが出来たが、0.89では出来なくなった。
(でも列ファミリーを削除することによって、列ファミリーが全く無い状態にすることは出来るようだ…)
hbase(main):019:0> create 'test3',{NAME => 'data1',VERSIONS => 1} 0 row(s) in 2.1560 seconds
パラメーター名 | デフォルト値 | 説明 |
---|---|---|
NAME | 列ファミリー名 | |
VERSIONS | 3 | 最大履歴数(履歴管理する最大件数) |
COMPRESSION | NONE | |
IN_MEMORY | false | |
BLOCKCACHE | true | |
BLOCKSIZE | 64 * 1024 | 65536 |
TTL | Integer.MAX_VALUE | Time-to-live(以前のデフォルト値は-1だったらしい) |
BLOOMFILTER | NONE | |
REPLICATION_SCOPE | 0 | 0:ローカル、1:グローバル |
テーブルを削除するコマンド。
→Java APIのdeleteTable()
削除する前にテーブルを使用不可にしておく必要がある。
hbase(main):034:0> drop 'test2' ERROR: Table test2 is enabled. Disable it first.' hbase(main):035:0> disable 'test2' 0 row(s) in 2.0630 seconds hbase(main):036:0> drop 'test2' 0 row(s) in 0.3210 seconds
テーブルの使用可否を切り替えるコマンド。
(テーブルの定義を変更する際はテーブルを使用不可にする必要がある)
→Java APIのdisableTable()・enableTable()
hbase(main):024:0> disable 'test' 0 row(s) in 1.1400 seconds
hbase(main):025:0> enable 'test' 0 row(s) in 0.3440 seconds
テーブルの定義を表示するコマンド。
→Java APIのgetTableDescriptor()
hbase(main):043:0> describe 'test2' DESCRIPTION ENABLED {NAME => 'test2', FAMILIES => [{NAME => 'data1', BL true OOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COMP RESSION => 'NONE', VERSIONS => '3', TTL => '2147483 647', BLOCKSIZE => '65536', IN_MEMORY => 'false', B LOCKCACHE => 'true'}]} 1 row(s) in 0.0470 seconds
右の方にまぎれて表示されているENABLEDのtrue/falseは、テーブルの使用可否の状態を表している。
→Java APIのisTableEnabled()
テーブルの定義を変更するコマンド。
(変更する前にテーブルを使用不可にしておく必要がある)
METHODにtable_attとdelete以外を指定する(もしくはMETHODを省略する)と、列ファミリーの属性の変更になる。
列ファミリーが存在していなかった場合は列ファミリーの追加となる。
hbase(main):055:0> alter 'test2',{NAME=>'data2'} …data2が無ければ追加される 0 row(s) in 0.1100 seconds
VERSIONSを変更するには以下のようにする。
hbase(main):053:0> alter 'test2',{NAME=>'data1', VERSIONS=>1} 0 row(s) in 0.1090 seconds
→Java APIのaddColumn()・modifyColumn()
0.89では、1つの列ファミリーを変更するだけなら、とげ括弧でくくらなくてもよくなった。
hbase(main):053:0> alter 'test2', NAME=>'data1', VERSIONS=>1
列ファミリーを削除する場合はMETHODにdeleteを指定する。
hbase(main):061:0> alter 'test2',{NAME=>'data2', METHOD=>'delete'} 0 row(s) in 0.1250 seconds
0.89では、以下のように短縮した書き方も可能。
hbase(main):061:0> alter 'test2', 'delete'=>'data2'
テーブル属性(MAX_FILESIZE・MEMSTORE_FLUSHSIZE・READONLY・DEFERRED_LOG_FLUSH)を変更する場合はMETHODにtable_attを指定する。
hbase(main):001:0> alter 'test2',{METHOD=>'table_att', READONLY=>true}
テーブルのデータをクリアする、というかテーブルを再作成するコマンド。
テーブルを使用不可にし、dropしてから再作成する。
hbase(main):003:0> truncate 'test2' Truncating 'test2' table (it may take a while): - Disabling table... - Dropping table... - Creating table... 0 row(s) in 3.7350 seconds
テーブルにデータをセットするコマンド。
(データが存在していなければ追加になる。データが存在していれば更新になる)
→Java APIのPut
例 | 備考 |
---|---|
hbase(main):001:0> put 'test','key1','data','value1' 0 row(s) in 1.1090 seconds hbase(main):002:0> put 'test','key1','data:','value1' 0 row(s) in 0.0780 seconds |
testテーブルにROW(キー)='key1'で 列「data : 」(qualifier無し)に値「value1」を登録。 |
hbase(main):018:0> put 'test','key1','data:q1','value2' 0 row(s) in 0.1410 seconds |
testテーブルにROW(キー)='key1'で 列「data : q1」(qualifier有り)に値「value2」を登録。 |
hbase(main):026:0> put 'test','key1','data:','value3',1267846496789 0 row(s) in 0.1100 seconds |
時刻付きで値を登録。 |
データ(セル)はバージョン管理されており、日時(timestamp)を暗黙に持っている。
日時を明示しなかった場合は、現在日時で登録される。
指定した日時が既に存在していた場合は上書きされる。
指定した日時が最も古いバージョンよりも古くて履歴最大件数(VERSIONS)よりも前になる場合は登録されない。(指定する日時によって登録されたりされなかったり?)
データ(セル)をlong型とみなして値を加算する。[2010-07-12]
→Java APIのincrementColumnValue
例 | 備考 |
---|---|
hbase(main):032:0> put 'test2','cnt1','data:cnt',"\x00\x00\x00\x00\x00\x00\x00\x01" 0 row(s) in 0.0310 seconds hbase(main):033:0> get_counter 'test2','cnt1','data:cnt' COUNTER VALUE = 1 hbase(main):034:0> incr 'test2','cnt1','data:cnt',10 COUNTER VALUE = 11 hbase(main):035:0> get_counter 'test2','cnt1','data:cnt' COUNTER VALUE = 11 |
JRubyでどうやってlong値を指定すればいいのか知らないので、適当(爆) |
hbase(main):036:0> incr 'test2','cnt1','data:cnt' COUNTER VALUE = 12 |
値を省略すると、1だけ加算される。 |
long型でない値(8バイトより短いデータ)が入っていると、例外が発生する。
hbase(main):037:0> put 'test2','cnt','data:cnt7',"\x00\x00\x00\x00\x00\x00\x01"
0 row(s) in 0.0320 seconds
hbase(main):038:0> incr 'test2','cnt','data:cnt7'
ERROR: org.apache.hadoop.hbase.client.RetriesExhaustedException: Trying to contact region server hishidama.mshome.hishidama:3756
for region test2,,1278436772812.cccde534003226e65c9eacc819df70f6., row 'cnt', but failed after 7 attempts.
Exceptions:
java.io.IOException: java.io.IOException: java.lang.IllegalArgumentException: offset (31) + length (8) exceed the capacity of the array: 38
at org.apache.hadoop.hbase.util.Bytes.explainWrongLengthOrOffset(Bytes.java:502)
at org.apache.hadoop.hbase.util.Bytes.toLong(Bytes.java:480)
at org.apache.hadoop.hbase.regionserver.HRegion.incrementColumnValue(HRegion.java:3023)
〜
また、qualifierの無い列ファミリーを指定すると、例外が発生する…。
hbase(main):039:0> put 'test2','cnt','data',"\x00\x00\x00\x00\x00\x00\x00\x01"
0 row(s) in 0.0630 seconds
hbase(main):040:0> get_counter 'test2','cnt','data'
COUNTER VALUE = 1
hbase(main):041:0> incr 'test2','cnt','data'
ERROR: org.apache.hadoop.hbase.client.RetriesExhaustedException: Trying to contact region server hishidama.mshome.hishidama:3756
for region test2,,1278436772812.cccde534003226e65c9eacc819df70f6., row 'cnt', but failed after 7 attempts.
Exceptions:
java.io.IOException: java.io.IOException: java.lang.NullPointerException
at org.apache.hadoop.hbase.regionserver.ColumnCount.<init>(ColumnCount.java:47)
at org.apache.hadoop.hbase.regionserver.ExplicitColumnTracker.<init>(ExplicitColumnTracker.java:65)
at org.apache.hadoop.hbase.regionserver.QueryMatcher.<init>(QueryMatcher.java:142)
at org.apache.hadoop.hbase.regionserver.Store.get(Store.java:1318)
at org.apache.hadoop.hbase.regionserver.HRegion.incrementColumnValue(HRegion.java:3017)
〜
HBase0.20.5のincrと異なり、列ファミリー名に「:
」を付けていても同様の例外が発生する。
hbase(main):041:0> incr 'test2','cnt','data:'
テーブルのデータ(セル)を表示するコマンド。
→Java APIのGet
例 | 備考 |
---|---|
hbase(main):060:0> get 'test','key1' COLUMN CELL data: timestamp=1278419161109, value=value1 data:q1 timestamp=1278419165859, value=value2 2 row(s) in 0.0160 seconds |
testテーブルのROW(キー)='key1'の 各データ(最新版)を全て表示。 |
hbase(main):062:0> get 'test','key1',{COLUMN=>'data:'} COLUMN CELL data: timestamp=1278419161109, value=value1 data:q1 timestamp=1278419165859, value=value2 2 row(s) in 0.0160 seconds |
列名を指定。 (COLUMNSでも通るっぽい) 0.20では「data:」だけ表示されたと思うが、 0.89では「data:」で始まる列が全て取れるらしい。 |
hbase(main):064:0> get 'test','key1',{COLUMN=>'data:',TIMESTAMP=>1278419161109} COLUMN CELL data: timestamp=1278419161109, value=value1 1 row(s) in 0.0160 seconds |
列名とバージョン(日時)を指定。 |
hbase(main):065:0> get 'test','key1',{COLUMN=>'data:q1',VERSIONS=>5} COLUMN CELL data:q1 timestamp=1278419428265, value=value2 data:q1 timestamp=1278419425968, value=value0 data:q1 timestamp=1278419165859, value=value2 3 row(s) in 0.0150 seconds |
表示する最大履歴数を指定。 |
hbase(main):066:0> get 'TEST_TYPE','KEY00001',{COLUMN=>['ColumnFamilyA:','ColumnFamilyB:']} COLUMN CELL ColumnFamilyA: timestamp=1269893838171, value=k1_cfA0 ColumnFamilyA:Column timestamp=1269893838203, value=k1_cfA_c11 〜 8 row(s) in 0.0940 seconds |
複数の列名を指定。 |
表示する履歴件数(VERSIONS)を指定すると、その件数までのバージョンが表示される。
ただしそもそもテーブル定義でVERSIONSを指定(デフォルトは3件)していると、そのバージョン数までしか管理されていない。
データ(セル)をlong型とみなして値を表示する。(incrで加算した値を表示できる)
例 | 備考 |
---|---|
hbase(main):085:0> put 'test2','cnt','data',"\x00\x00\x00\x00\x00\x00\x02\x01" 0 row(s) in 0.0470 seconds hbase(main):086:0> get 'test2','cnt','data' COLUMN CELL data: timestamp=1278439515000, value=\x00\x00\x00\x00\x00\x00\x02\x01 1 row(s) in 0.0150 seconds hbase(main):087:0> get_counter 'test2','cnt','data' COUNTER VALUE = 513 |
JRubyでどうやってlong値を指定すればいいのか知らないので、適当(爆) |
データが8バイト以上無いとエラーになる。(8バイトより多い場合は先頭8バイトが使用される)
ERROR: java.lang.IllegalArgumentException: offset (0) + length (8) exceed the capacity of the array: 1
データ(セル)の特定バージョンを削除するコマンド。
(全バージョンを消したい場合はdeleteallを使用する)
→Java APIのDelete(deleteColumn())
例 | 備考 |
---|---|
hbase(main):007:0> delete 'test','key1','data:' 0 row(s) in 0.0150 seconds |
testテーブルのROW(キー)='key1'の列「data: 」の最新セルを削除。 |
hbase(main):008:0> delete 'test','key1','data:',1278419428265 |
日時(バージョン)を指定。 |
削除されるのは指定した日時のデータ(セル)のみ。省略時は最新版。
なので、最新版を削除すると、その前のバージョンの値がget等で取得されることになる。
データ(セル)の全履歴を削除するコマンド。
→Java APIのDelete(deleteColumns())
例 | 備考 |
---|---|
hbase(main):018:0> deleteall 'test','key1','data:' 0 row(s) in 0.0160 seconds |
testテーブルのROW(キー)='key1'の列「data: 」を削除。 |
hbase(main):021:0> deleteall 'test','key1' 0 row(s) in 0.0150 seconds |
testテーブルの指定されたキーの全データ(セル)を削除。 (RDB(SQL)のdelete文に相当) |
hbase(main):052:0> deleteall 'test','key1',nil,1267903199750 0 row(s) in 0.0160 seconds |
時刻を指定。 (列名にnilを指定しているので、全列が対象) |
テーブルのレコード数(ROWの個数)を表示するコマンド。
(似た機能:RowCounterクラス)
例 | 備考 |
---|---|
hbase(main):068:0> count 'TEST_TYPE' 1 row(s) in 0.0460 seconds |
TEST_TYPEテーブルの件数を表示。 |
hbase(main):069:0> count 'student',2 Current count: 2, row: 102 Current count: 4, row: 104 Current count: 6, row: 202 Current count: 8, row: 205 8 row(s) in 0.0470 seconds hbase(main):003:0> count 'test', INTERVAL=>1000 Current count: 1000, row: 1899 Current count: 2000, row: 2799 Current count: 3000, row: 3699 Current count: 4000, row: 4599 4653 row(s) in 0.5620 seconds |
中間ログ出力の指定。 2を指定すると、2件毎に処理途中での件数を表示する。 デフォルトは1000件ずつ。 |
hbase(main):003:0> count 'test', CACHE=>10000 Current count: 1000, row: 1899 Current count: 2000, row: 2799 Current count: 3000, row: 3699 Current count: 4000, row: 4599 4653 row(s) in 0.1410 seconds |
キャッシュを指定すると、実行が早くなるようだ。 デフォルトのキャッシュは10件。 |
テーブルの全データを表示するコマンド。
→Java APIのScan
例 | 備考 |
---|---|
hbase(main):080:0> scan 'test2' ROW COLUMN+CELL key1 column=data:, timestamp=1278436776718, value=value1 key1 column=data:q1, timestamp=1278436776765, value=value2 key1 column=data:q2, timestamp=1278436777078, value=value5 key2 column=data:, timestamp=1278436776859, value=value3 key3 column=data:, timestamp=1278436776984, value=value4 key3 column=data:q1, timestamp=1278436889296, value=value6 3 row(s) in 0.0320 seconds |
testテーブルの全データ(セル)を表示。 (RDB(SQL)のselect文に相当) |
hbase(main):089:0> scan 'test2',{COLUMNS=>'data:q1'} ROW COLUMN+CELL key1 column=data:q1, timestamp=1278436776765, value=value2 key3 column=data:q1, timestamp=1278436889296, value=value6 2 row(s) in 0.0150 seconds |
列名を指定。 |
hbase(main):090:0> scan 'test2',{COLUMNS=>['data:q1','data:q2']} ROW COLUMN+CELL key1 column=data:q1, timestamp=1278436776765, value=value2 key1 column=data:q2, timestamp=1278436777078, value=value5 key3 column=data:q1, timestamp=1278436889296, value=value6 2 row(s) in 0.0320 seconds |
複数列を指定。 |
hbase(main):091:0> scan 'test2',{STARTROW=>'key2'} ROW COLUMN+CELL key2 column=data:, timestamp=1278436776859, value=value3 key3 column=data:, timestamp=1278436776984, value=value4 key3 column=data:q1, timestamp=1278436889296, value=value6 2 row(s) in 0.0470 seconds hbase(main):093:0> scan 'test2',{STOPROW=>'key2'} ROW COLUMN+CELL key1 column=data:, timestamp=1278436776718, value=value1 key1 column=data:q1, timestamp=1278436776765, value=value2 key1 column=data:q2, timestamp=1278436777078, value=value5 1 row(s) in 0.0310 seconds |
ROW(キー)の範囲を指定。 STARTROWは“それ以降(STARTROW自身を含む)”の指定。 STOPROWは“それより前(STOPROW自身を含まない)”の指定。 |
hbase(main):097:0> scan 'test2',{LIMIT=>2} ROW COLUMN+CELL key1 column=data:, timestamp=1278436776718, value=value1 key1 column=data:q1, timestamp=1278436776765, value=value2 key1 column=data:q2, timestamp=1278436777078, value=value5 key2 column=data:, timestamp=1278436776859, value=value3 2 row(s) in 0.0310 seconds |
表示レコード数を制限。 (ROW数の制限であって、表示されるセル数の制限ではない) |
hbase(main):101:0> scan 'test2',{MAXLENGTH=>32} ROW COLUMN+CELL key1 column=data:, timestamp=1278436776718, value=v key1 column=data:q1, timestamp=1278436776765, value=v key1 column=data:q2, timestamp=1278436777078, value=v key2 column=data:, timestamp=1278436776859, value=v key3 column=data:, timestamp=1278436776984, value=v key3 column=data:q1, timestamp=1278436889296, value=v 3 row(s) in 0.0310 seconds |
表示桁数を指定。 (各行の「timestamp〜」以降の文字数を指定するもの) |
hbase(main):109:0> scan 'test2',{VERSIONS=>2, STOPROW=>'key2'}
ROW COLUMN+CELL
key1 column=data:, timestamp=1278437135750, value=value1
key1 column=data:, timestamp=1278437135703, value=value15
key1 column=data:q1, timestamp=1278436776765, value=value2
key1 column=data:q2, timestamp=1278436777078, value=value5
1 row(s) in 0.0310 seconds
|
表示履歴数を指定。 デフォルトはVERSIONS=>1なので、最新データしか表示されない。 |
hbase(main):110:0> scan 'test2',{TIMESTAMP=>1278436776859} ROW COLUMN+CELL key2 column=data:, timestamp=1278436776859, value=value3 1 row(s) in 0.0310 seconds |
日時(タイムスタンプ)を指定。 |
hbase(main):114:0> import org.apache.hadoop.hbase.filter.ValueFilter => Java::OrgApacheHadoopHbaseFilter::ValueFilter hbase(main):150:0> import org.apache.hadoop.hbase.filter.BinaryComparator => Java::OrgApacheHadoopHbaseFilter::BinaryComparator hbase(main):151:0> filter=ValueFilter.new(ValueFilter::CompareOp::EQUAL, hbase(main):152:1* BinaryComparator.new("value1".to_java_bytes)) => #<Java::OrgApacheHadoopHbaseFilter::ValueFilter:0x16bbeaf> hbase(main):155:0> scan 'test2',{"FILTER"=>filter} ROW COLUMN+CELL key1 column=data:, timestamp=1278437135750, value=value1 1 row(s) in 0.0310 seconds |
値が「value1」であるセルを全て取得。 (ヘルプには載っていないが)scanにはフィルターを指定できる。 「FILTER」という定数は定義されていないので、クォーテーションで囲む必要がある。 FilterはJavaの(HBaseの)クラスなので、インスタンスを作って渡す。 →JavaAPIのFilter |
HBase ShellはJRuby(HBASE_HOME/bin/hirb.rbやHBase.rb)で書かれており、対話ツール上からもJRubyの文が書ける。
hbase(main):001:0> java.text.SimpleDateFormat.new("yyyy/MM/dd HH:mm:ss.SSS").format(1267861000875)
=> "2010/03/06 16:36:40.875"
hbase(main):002:0> import java.text.SimpleDateFormat => Java::JavaText::SimpleDateFormat hbase(main):012:0> SimpleDateFormat.new("yyyy/MM/dd HH:mm:ss.SSS").format(1267861000875) => "2010/03/06 16:36:40.875"
hbase(main):004:0> sdf=java.text.SimpleDateFormat.new("yyyy/MM/dd HH:mm:ss.SSS") => #<Java::JavaText::SimpleDateFormat:0xb125bd> hbase(main):005:0> sdf.parse('2010/03/06 12:34:56.789').getTime() => 1267846496789