lakefs 对象模型-对象存储

了解lakefs 的对象模型对于我们更好的学习lakefs 是比较重要的

lakefs 对象存储

对象存储借鉴自s3,包含一些特性

  • 包含一些内容,无限大小以及格式
  • 一些元数据,大小,创建时间,时间戳,内容检查值,
  • 一些用户自定义的元数据
    和其他对象存储类似,lakfe 的对象是不可变的,不能重写,可以被整体的替换以及删除,但是不能修改
    路径是一个可读的url,典型是utf-8 编码的,lakefs 路径与对象的映射是基于特定的规则(lakefs 协议)

说明

lakefs 的对象存储是自己基于golang 的http包,写的s3 gateway层处理,具体代码在pkg/gateway/handler.go 中
对于不同操作的包装可以参考pkg/gateway/operations 里边包含了get,put,delete 等操作,也是值得学习的包含了如何
编写一个s3 gateway服务,如果想偷懒的话,minio 的gateway 是一个可以直接拿来使用的比如juicefs 就使用的minio
对于lakefs 的http api 服务以及s3 gateway 服务lakefs 是复用了一个链接,对于处理的时候基于特征进行简单路由

 
server := &http.Server{
  Addr: cfg.GetListenAddress(),
  Handler: http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
    // If the request has the S3 GW domain (exact or subdomain) - or carries an AWS sig, serve S3GW
    if httputil.HostMatches(request, cfg.GetS3GatewayDomainNames()) ||
      httputil.HostSubdomainOf(request, cfg.GetS3GatewayDomainNames()) ||
      sig.IsAWSSignedRequest(request) {
      s3gatewayHandler.ServeHTTP(writer, request)
      return
    }
 
    // Otherwise, serve the API handler
    apiHandler.ServeHTTP(writer, request)
  }),
}

包装的ServeHttp

func OperationHandler(sc *ServerContext, handler operations.AuthenticatedOperationHandler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
    ctx := req.Context()
    o := ctx.Value(ContextKeyOperation).(*operations.Operation)
    perms, err := handler.RequiredPermissions(req)
    if err != nil {
      _ = o.EncodeError(w, req, gatewayerrors.ErrAccessDenied.ToAPIErr())
      return
    }
    authOp := authorize(w, req, sc.authService, perms)
    if authOp == nil {
      return
    }
    handler.Handle(w, req, authOp)
  })
}

参考s3 response 响应处理,基于EncodeError 以及EncodeResponse方法

func (controller *ListBuckets) Handle(w http.ResponseWriter, req *http.Request, o *AuthorizedOperation) {
  o.Incr("list_repos")
  repos, _, err := o.Catalog.ListRepositories(req.Context(), -1, "", "")
  if err != nil {
    _ = o.EncodeError(w, req, errors.Codes.ToAPIErr(errors.ErrInternalError))
    return
  }
 
  // assemble response
  buckets := make([]serde.Bucket, len(repos))
  for i, repo := range repos {
    buckets[i] = serde.Bucket{
      CreationDate: serde.Timestamp(repo.CreationDate),
      Name:         repo.Name,
    }
  }
  // write response
  o.EncodeResponse(w, req, serde.ListAllMyBucketsResult{
    Buckets: serde.Buckets{Bucket: buckets},
  }, http.StatusOK)
}

参考资料

https://docs.lakefs.io/reference/object-model.html

posted on 2022-02-11 19:33  荣锋亮  阅读(264)  评论(0编辑  收藏  举报

导航