Chris Lu
12 years ago
7 changed files with 189 additions and 28 deletions
-
7weed-fs/note/startup_process.txt
-
48weed-fs/src/pkg/storage/volume_info.go
-
25weed-fs/src/pkg/topology/data_node.go
-
28weed-fs/src/pkg/topology/node.go
-
40weed-fs/src/pkg/topology/topology.go
-
48weed-fs/src/pkg/topology/volume_layout.go
-
21weed-fs/src/pkg/topology/volume_location.go
@ -1,7 +0,0 @@ |
|||||
1. clients report its own server info, volumes info, |
|
||||
2. master collect all volumes, separated into readable volumes, writable volumes, volume2machine mapping |
|
||||
machines is an array of machine info |
|
||||
writable volumes is an array of vids |
|
||||
vid2machineId maps volume id to machineId, which is the index of machines array |
|
||||
|
|
||||
|
|
@ -1,10 +1,50 @@ |
|||||
package storage |
package storage |
||||
|
|
||||
import ( |
|
||||
|
import () |
||||
|
|
||||
|
type VolumeInfo struct { |
||||
|
Id VolumeId |
||||
|
Size int64 |
||||
|
ReplicationType ReplicationType |
||||
|
} |
||||
|
type ReplicationType int |
||||
|
|
||||
|
const ( |
||||
|
Copy00 = ReplicationType(00) // single copy
|
||||
|
Copy01 = ReplicationType(01) // 2 copies, each on different racks, same data center
|
||||
|
Copy10 = ReplicationType(10) // 2 copies, each on different data center
|
||||
|
Copy11 = ReplicationType(11) // 3 copies, 2 on different racks and local data center, 1 on different data center
|
||||
|
Copy20 = ReplicationType(20) // 3 copies, each on dffereint data center
|
||||
|
LengthRelicationType = 5 |
||||
) |
) |
||||
|
|
||||
type VolumeInfo struct { |
|
||||
Id VolumeId |
|
||||
Size int64 |
|
||||
|
func GetReplicationLevelIndex(v *VolumeInfo) int { |
||||
|
switch v.ReplicationType { |
||||
|
case Copy00: |
||||
|
return 0 |
||||
|
case Copy01: |
||||
|
return 1 |
||||
|
case Copy10: |
||||
|
return 2 |
||||
|
case Copy11: |
||||
|
return 3 |
||||
|
case Copy20: |
||||
|
return 4 |
||||
|
} |
||||
|
return -1 |
||||
|
} |
||||
|
func GetCopyCount(v *VolumeInfo) int { |
||||
|
switch v.ReplicationType { |
||||
|
case Copy00: |
||||
|
return 1 |
||||
|
case Copy01: |
||||
|
return 2 |
||||
|
case Copy10: |
||||
|
return 2 |
||||
|
case Copy11: |
||||
|
return 3 |
||||
|
case Copy20: |
||||
|
return 3 |
||||
|
} |
||||
|
return 0 |
||||
} |
} |
@ -0,0 +1,48 @@ |
|||||
|
package topology |
||||
|
|
||||
|
import ( |
||||
|
"errors" |
||||
|
"fmt" |
||||
|
"math/rand" |
||||
|
"pkg/storage" |
||||
|
) |
||||
|
|
||||
|
type VolumeLayout struct { |
||||
|
vid2location map[storage.VolumeId]*DataNodeLocationList |
||||
|
writables []storage.VolumeId // transient array of writable volume id
|
||||
|
pulse int64 |
||||
|
volumeSizeLimit uint64 |
||||
|
} |
||||
|
|
||||
|
func NewVolumeLayout(volumeSizeLimit uint64, pulse int64) *VolumeLayout { |
||||
|
return &VolumeLayout{ |
||||
|
vid2location: make(map[storage.VolumeId]*DataNodeLocationList), |
||||
|
writables: *new([]storage.VolumeId), |
||||
|
pulse: pulse, |
||||
|
volumeSizeLimit: volumeSizeLimit, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (vl *VolumeLayout) RegisterVolume(v *storage.VolumeInfo, dn *DataNode) { |
||||
|
if _, ok := vl.vid2location[v.Id]; !ok { |
||||
|
vl.vid2location[v.Id] = NewDataNodeLocationList() |
||||
|
} |
||||
|
vl.vid2location[v.Id].Add(dn) |
||||
|
if len(vl.vid2location[v.Id].list) >= storage.GetCopyCount(v) { |
||||
|
vl.writables = append(vl.writables,v.Id) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (vl *VolumeLayout) PickForWrite(count int) (int, *DataNodeLocationList, error) { |
||||
|
len_writers := len(vl.writables) |
||||
|
if len_writers <= 0 { |
||||
|
fmt.Println("No more writable volumes!") |
||||
|
return 0, nil, errors.New("No more writable volumes!") |
||||
|
} |
||||
|
vid := vl.writables[rand.Intn(len_writers)] |
||||
|
locationList := vl.vid2location[vid] |
||||
|
if locationList != nil { |
||||
|
return count, locationList, nil |
||||
|
} |
||||
|
return 0, nil, errors.New("Strangely vid " + vid.String() + " is on no machine!") |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
package topology |
||||
|
|
||||
|
import ( |
||||
|
) |
||||
|
|
||||
|
type DataNodeLocationList struct { |
||||
|
list []*DataNode |
||||
|
} |
||||
|
|
||||
|
func NewDataNodeLocationList() *DataNodeLocationList { |
||||
|
return &DataNodeLocationList{} |
||||
|
} |
||||
|
|
||||
|
func (dnll *DataNodeLocationList) Add(loc *DataNode){ |
||||
|
for _, dnl := range dnll.list { |
||||
|
if loc.ip == dnl.ip && loc.port == dnl.port { |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
dnll.list = append(dnll.list, loc) |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue