• No results found

Designing a Concurrent File Server

N/A
N/A
Protected

Academic year: 2021

Share "Designing a Concurrent File Server"

Copied!
22
0
0

Loading.... (view fulltext now)

Full text

(1)

Designing a

Concurrent File

Server

James Whitehead II University of Oxford jim.whitehead@cs.ox.ac.uk 28 August 2012

(2)

Building CSP Style Concurrent Systems

• Disciplined model of concurrency

• Build applications

• Web server (CPA 2011) • File system server

• Range of designs

(3)

Go Programming Language

• Robert Griesemer, Rob Pike, Ken Thompson

• Fast compilation

• Lightweight type system

• Garbage collected

(4)

Concurrency in Go

• Can FORK goroutines using ‘go’ keyword

• No PAR/FORKING block

• Any-to-any channels

• ALT using ‘select’

• Cites CSP (but not occam)

“Don’t communicate by sharing memory, share memory by communicating”

(5)

File servers

• Contention for resources

• Low-level I/O

• Shared data (disk)

• Shared memory

(6)

File server concurrency

• Highly concurrent with explicit locks (UNIX, Linux)

• No concurrency (MINIX)

• “Simple” source code • Embarrassingly sequential

MINIX provides a clean slate from which to derive the design of a concurrent file system.

(7)

Existing architecture

proc

system call interface proc proc

FS Server

inode table

block cache syscall implementations

dev dev dev

message procedure call

(8)

Opportunities for concurrency

• Files must be opened for I/O

• File descriptors

• Available until closed

• read, write, seek, etc.

An I/O operation concurrently with a normal system call.

(9)

A step in the right direction...

proc

system call interface

proc proc

dev dev dev

block cache inode table

I/O server FS server

alloc table

• New I/O server

• Explicit dependencies

• All sequential processes

Not free from hazards...

• Size of a file

• Updated in write (I/O)

• Read in stat (FS)

(10)

Trickle-down concurrency

Reduced the complexity of atomic actions, introducing three new bottlenecks.

• Block cache

• Inode table

• Alloc table

(11)

Block cache concurrency

• Cache-hit

• Return the block immediately

• Cache-miss

• Spawn new goroutine to load block • Continue serving other requests • Return block when ready

(12)

Concurrent I/O Server

• Two open files are independent

• No shared blocks

• No shared inodes

• Allow CREW concurrency for each file

Shared file descriptors must be addressed..

(13)

A compromise...

proc

system call interface proc proc

dev dev dev block cache inode table FS server alloc table I/O Server fd fd fd file file

(14)

Design

Overall:

• Process encapsulation

• Eliminate implicit sharing

• Connections and interaction

• Easy to reason about

Individual:

• Sequential is simple

• Concurrency applied carefully

(15)

A roadblock..

• Concurrent file I/O

• Sequential (other) system calls

• Inodes are shared (disk, memory)

• Standards (under) specification

(16)

Conclusions

• Compromise between sequential and highly concurrent

• Disciplined model of concurrency

• Iterative (and careful) introduction

• Techniques for addressing concurrency needs

(17)
(18)

Unit testing concurrency

Want to show that a slow/broken device doesn’t break the system, unit testing the concurrency properties.

• Create a broken device

• Use channels to order operations

• Interfaces and concurrency

(19)

Setup

type BlockDevice interface {

Read(buf interface{}, pos int64) error Write(buf interface{}, pos int64) error }

type BlockingDevice struct { BlockDevice

HasBlocked chan int64 // position argument

Unblock chan bool

}

func (dev *BlockingDevice) Read(buf interface{}, pos int64) error { dev.HasBlocked <- pos

<-dev.Unblock

return dev.BlockDevice.Read(buf, pos) }

(20)

Blocking a device

// create a block cache with test device, and a broken device

cache := createTestCache() bdev := createBlockingDevice() cache.MountDevice(1, bdev)

// to join the spawned goroutines (manual PAR)

done := make(chan bool) go func() {

// do a read on the broken device (1)

cb := cache.GetBlock(1, SUPER_BLOCK) cache.PutBlock(cb)

done <- true }()

(21)

Testing the cache

go func() {

// wait for the device to be blocked

<-bdev.HasBlocked

// then request a read from the non-broken device

cb := cache.GetBlock(0, SUPER_BLOCK)

// now release the broken device so it cleanly shuts down

bdev.Unblock <- true cache.PutBlock(cb) done <- true }()

// wait for both goroutines to finish

<-done <-done

(22)

Questions? Comments?

References

Related documents

The Active Factory ArchestrAServer.lic license file (Per Named Device, Per Named User, and Per Server/Concurrent) is installed on a license server (usually the Historian database

Shifts in supply curve- Increase or Decrease in Supply Increase in supply- Quantity supplied increases due to change in factors other than price.. This shifts the supply

This paper has covered the best practices for setting up Aras Innovator 10 on a SQL Server 2012 Enterprise Edition server designed to scale to from under 25,000 concurrent users

Cases of lameness that do not usually result in swelling of the digit include papillomatous digital dermatitis (hairy warts), interdigital dermatitis, sole ulcers, laminitis,

In this multipurpose cohort of university graduates we observed an attenuation in the association between high BMI and the risk of developing T2DM in participants with better

This document provides a basic introduction to the built-in file sharing options in Mac OS X - how to setup file sharing on one computer, and how to access those shared files

The budget request presented here attempts to strike a balance between investments in technology and human capital. It is clear that the Commission is facing an

1.3.7 Diving bell means a submersible compression chamber, including its fitted equipment , for transfer of diving personnel under pressure be- tween the work