Documente Academic
Documente Profesional
Documente Cultură
edu
Scalable IO in Java
Outline
http://gee.cs.oswego.edu
"
"
"
"
Network Services
"
http://gee.cs.oswego.edu
#eb services) Distributed Ob$ects) etc !ost "ave sa*e basic structure+
Read request Decode request Process service Encode reply Send reply
"
"
read
send
"andler
read decode co*pute encode send
"andler
read decode co*pute encode send
"andler
Scalability !oals
"
http://gee.cs.oswego.edu
.raceful degradation under increasing load /*ore clients0 1ontinuous i*prove*ent wit" increasing resources /1(U) *e*ory) disk) bandwidt"0 'lso *eet availability and perfor*ance goals
S"ort latencies !eeting peak de*and 2unable 3uality of service
"
"
"
Divide-and-con3uer is usually t"e best approac" for ac"ieving any scalability goal
http://gee.cs.oswego.edu
"
"
"andler
"
Event"driven Designs
"
http://gee.cs.oswego.edu
Don6t usually need a t"read per client Less conte4t switc"ing) often less locking !ust *anually bind actions to events
Less over"ead
"
"
Si*ilar to .U& event-driven actions 1annot eli*inate all blocking+ .1) page faults) etc
utton
click8
Reactor Pattern
"
http://gee.cs.oswego.edu
"
"
"
acceptor
read
)ava*nio Support
"
http://gee.cs.oswego.edu
C+annels
1onnections to files) sockets etc t"at support non-blocking reads
"
#u,,ers
'rray-like ob$ects t"at can be directly read or written by 1"annels
"
Selectors
2ell w"ic" of a set of 1"annels "ave &O events
"
Selection-eys
!aintain &O event status and bindings
Reactor .$ Setup
http://gee.cs.oswego.edu
class Reactor implements Runnable { final Selector selector; final ServerSocketChannel serverSocket; Reactor(int port) throws IOException { selector = Selector.open(); serverSocket = ServerSocketChannel.open(); serverSocket.socket().bind( new InetSocketAddress(port)); serverSocket.configureBlocking(false); SelectionKey sk = serverSocket.register(selector, SelectionKey.OP_ACCEPT); sk.attach(new Acceptor()); }
/* Alternatively, use explicit SPI provider: SelectorProvider p = SelectorProvider.provider(); selector = p.openSelector(); serverSocket = p.openServerSocketChannel(); */
Reactor 0$ %cceptor
http://gee.cs.oswego.edu
// class Reactor continued class Acceptor implements Runnable { // inner public void run() { try { SocketChannel c = serverSocket.accept(); if (c != null) new Handler(selector, c); } catch(IOException ex) { /* ... */ } } } }
client client client acceptor
read read read
Reactor dispatc"
decode co*pute encode decode co*pute encode decode co*pute encode send send send
http://gee.cs.oswego.edu
Per"State (andlers
"
http://gee.cs.oswego.edu
3ultit+readed Designs
"
http://gee.cs.oswego.edu
"
#orker 2"reads
Reactors s"ould 3uickly trigger "andlers
"
&orker '+reads
"
http://gee.cs.oswego.edu
"
"
"
2"read (ool
decode co*pute encode
worker t"reads
3ueued tasks
Coordinating 'asks
"
5andoffs
Eac" task enables) triggers) or calls ne4t one Usually fastest but can be brittle
http://gee.cs.oswego.edu
"
"
7ueues
-or e4a*ple) passing buffers across stages
"
-utures
#"en eac" task produces a result 1oordination layered on top of $oin or wait:notify
4sing PooledE5ecutor
"
' tunable worker t"read pool !ain *et"od execute(Runnable r) 1ontrols for+
2"e kind of task 3ueue /any 1"annel0 !a4i*u* nu*ber of t"reads !ini*u* nu*ber of t"reads ;#ar*; versus on-de*and t"reads <eep-alive interval until idle t"reads die
"
http://gee.cs.oswego.edu
" "
Saturation policy
"
http://gee.cs.oswego.edu
2"read (ool
decode co*pute encode
worker t"reads
3ueued tasks
http://gee.cs.oswego.edu
"
-ile transfer
'uto*ated file-to-net or net-to-file copying
"
!e*ory-*apped files
'ccess files via buffers
"
Direct buffers
1an so*eti*es ac"ieve =ero-copy transfer ut "ave setup and finali=ation over"ead est for applications wit" long-lived connections
Connection"#ased E5tensions
"
http://gee.cs.oswego.edu
"
E4a*ples
Databases and 2ransaction *onitors !ulti-participant ga*es) c"at) etc
"
%PI &alkt+roug+
"
http://gee.cs.oswego.edu
"
#u,,er
http://gee.cs.oswego.edu
abstract class Buffer { int capacity(); int position(); Buffer position(int newPosition); int limit(); Buffer limit(int newLimit); Buffer mark(); Buffer reset(); Buffer clear(); Buffer flip(); Buffer rewind(); int remaining(); boolean hasRemaining(); boolean isReadOnly(); }
#yte#u,,er 6.7
http://gee.cs.oswego.edu
abstract static static static static class ByteBuffer extends Buffer { ByteBuffer allocateDirect(int capacity); ByteBuffer allocate(int capacity); ByteBuffer wrap(byte[] src, int offset, int len); ByteBuffer wrap(byte[] src); isDirect(); order(); order(ByteOrder bo); slice(); duplicate(); compact(); asReadOnlyBuffer(); get(); get(int index); get(byte[] dst, int offset, int length); get(byte[] dst); put(byte b); put(int index, byte b); put(byte[] src, int offset, int length); put(ByteBuffer src); put(byte[] src); getChar(); getChar(int index); putChar(char value); putChar(int index, char value); asCharBuffer();
boolean ByteOrder ByteBuffer ByteBuffer ByteBuffer ByteBuffer ByteBuffer byte byte ByteBuffer ByteBuffer ByteBuffer ByteBuffer ByteBuffer ByteBuffer ByteBuffer char char ByteBuffer ByteBuffer CharBuffer
#yte#u,,er 6/7
short short ByteBuffer ByteBuffer ShortBuffer int int ByteBuffer ByteBuffer IntBuffer long long ByteBuffer ByteBuffer LongBuffer float float ByteBuffer ByteBuffer FloatBuffer double double ByteBuffer ByteBuffer DoubleBuffer } getShort(); getShort(int index); putShort(short value); putShort(int index, short value); asShortBuffer(); getInt(); getInt(int index); putInt(int value); putInt(int index, int value); asIntBuffer(); getLong(); getLong(int index); putLong(long value); putLong(int index, long value); asLongBuffer(); getFloat(); getFloat(int index); putFloat(float value); putFloat(int index, float value); asFloatBuffer(); getDouble(); getDouble(int index); putDouble(double value); putDouble(int index, double value); asDoubleBuffer();
http://gee.cs.oswego.edu
C+annel
http://gee.cs.oswego.edu
interface Channel { boolean isOpen(); void close() throws IOException; } interface ReadableByteChannel extends Channel { int read(ByteBuffer dst) throws IOException; } interface WritableByteChannel extends Channel { int write(ByteBuffer src) throws IOException; } interface ScatteringByteChannel extends ReadableByteChannel { int read(ByteBuffer[] dsts, int offset, int length) throws IOException; int read(ByteBuffer[] dsts) throws IOException; } interface GatheringByteChannel extends WritableByteChannel { int write(ByteBuffer[] srcs, int offset, int length) throws IOException; int write(ByteBuffer[] srcs) throws IOException; }
SelectableC+annel
http://gee.cs.oswego.edu
abstract class SelectableChannel implements Channel { int validOps(); boolean isRegistered(); SelectionKey keyFor(Selector sel); SelectionKey register(Selector sel, int ops) throws ClosedChannelException; void boolean Object } configureBlocking(boolean block) throws IOException; isBlocking(); blockingLock();
SocketC+annel
abstract class SocketChannel implements ByteChannel ... { static SocketChannel open() throws IOException;
http://gee.cs.oswego.edu
Socket int boolean boolean boolean boolean boolean boolean void void int int int int int int }
socket(); validOps(); isConnected(); isConnectionPending(); isInputOpen(); isOutputOpen(); connect(SocketAddress remote) throws IOException; finishConnect() throws IOException; shutdownInput() throws IOException; shutdownOutput() throws IOException; read(ByteBuffer dst) throws IOException; read(ByteBuffer[] dsts, int offset, int length) throws IOException; read(ByteBuffer[] dsts) throws IOException; write(ByteBuffer src) throws IOException; write(ByteBuffer[] srcs, int offset, int length) throws IOException; write(ByteBuffer[] srcs) throws IOException;
ServerSocketC+annel
http://gee.cs.oswego.edu
abstract class ServerSocketChannel extends ... { static ServerSocketChannel open() throws IOException; int validOps(); ServerSocket socket(); SocketChannel accept() throws IOException; }
8ileC+annel
abstract class FileChannel implements ... { int read(ByteBuffer dst); int read(ByteBuffer dst, long position); int read(ByteBuffer[] dsts, int offset, int length); int read(ByteBuffer[] dsts); int write(ByteBuffer src); int write(ByteBuffer src, long position); int write(ByteBuffer[] srcs, int offset, int length); int write(ByteBuffer[] srcs); long position(); void position(long newPosition); long size(); void truncate(long size); void force(boolean flushMetaDataToo); int transferTo(long position, int count, WritableByteChannel dst); int transferFrom(ReadableByteChannel src, long position, int count); FileLock lock(long position, long size, boolean shared); FileLock lock(); FileLock tryLock(long pos, long size, boolean shared); FileLock tryLock(); static final int MAP_RO, MAP_RW, MAP_COW; MappedByteBuffer map(int mode, long position, int size); } NOTE: ALL methods throw IOException
http://gee.cs.oswego.edu
Selector
http://gee.cs.oswego.edu
abstract class Selector { static Selector open() throws IOException; Set keys(); Set selectedKeys(); int selectNow() throws IOException; int select(long timeout) throws IOException; int select() throws IOException; void wakeup(); void close() throws IOException; }
Selection-ey
http://gee.cs.oswego.edu
abstract class SelectionKey { static final int OP_READ, OP_WRITE, OP_CONNECT, OP_ACCEPT; SelectableChannel channel(); Selector selector(); boolean isValid(); void cancel(); int interestOps(); void interestOps(int ops); int readyOps(); boolean isReadable(); boolean isWritable(); boolean isConnectable(); boolean isAcceptable(); Object attach(Object ob); Object attachment(); }