GAE: плюсы, минусы, подводные камни

Содержание

Слайд 2

GAE - что за неведомая фигня?

GAE - что за неведомая фигня?

Слайд 3

GAE это...

PaaS

Cloud Platform

Webapp hosting

managed

automatic scaling

BigTable

Go

JAVA

Python

GAE это... PaaS Cloud Platform Webapp hosting managed automatic scaling BigTable Go JAVA Python

Слайд 4

GAE это...

Игровая площадка Гвидо

GAE это... Игровая площадка Гвидо

Слайд 5

Ограничения GAE

Время выполнения запроса - 60 секунд (лучше - 30)
Данные на FS

Ограничения GAE Время выполнения запроса - 60 секунд (лучше - 30) Данные
- только чтение
Сохранение файлов - Google Datastore
Связь с внешними хостами - только AppEngine URL Fetch

Квоты:

Безопасность
Платные
OverQuotaError

http://www.google.com/enterprise/cloud/appengine/pricing.html

Слайд 6

Алиасы модулей:

logging
Django 1.2
jinja2 2.6
lxml 2.3
MarkupSafe 0.15
NumPy 1.6.1

PyCrypto 2.3
PyYAML 3.10
Python Imaging Library (PIL)

Алиасы модулей: logging Django 1.2 jinja2 2.6 lxml 2.3 MarkupSafe 0.15 NumPy
1.1.7
setuptools 0.6c11
webapp2 2.3
WebOb 1.1.

cPickle => pickle
cStringIO => StringIO
marshal, imp, ftplib, tempfile => None

Библиотеки:

Слайд 7

MVC?

model

view

controller

MVC? model view controller

Слайд 8

Backends

нет ограничений на время обработки
ручная конфигурация памяти/CPU
собственный поддомен
резидентность
приватные по умолчанию
API доступа

Backends нет ограничений на время обработки ручная конфигурация памяти/CPU собственный поддомен резидентность

Слайд 9

Datastore

ORM
GQL
Schemaless
Транзакции
Метаданные
Статистика
Асинхронность

Datastore ORM GQL Schemaless Транзакции Метаданные Статистика Асинхронность

Слайд 10

ORM

class Rate(db.Model):
    price = db.IntegerProperty()
    user = db.UserProperty(required=True)
    uptime = db.DateTimeProperty(auto_now=True)
    trade_unit = db.ReferenceProperty(TradeUnit, required=False)
    def put(self):
        q

ORM class Rate(db.Model): price = db.IntegerProperty() user = db.UserProperty(required=True) uptime = db.DateTimeProperty(auto_now=True)
= Rate.all().filter('trade_unit = ', self.trade_unit.key())
        q.order("-price")
        previous_rate = q.get()
        previous_price = previous_rate.price if previous_rate else 0
        price = previous_price + self.trade_unit.increase_rate
        if self.price < price:
            self.price = price
        super(Rate, self).put()

Слайд 11

GQL

SELECT [* | __key__]
  FROM
  WHERE [AND ...]
  ORDER

GQL SELECT [* | __key__] FROM WHERE [AND ...] ORDER BY [ASC
BY [ASC | DESC ] [, [ASC | DESC]... ]
  LIMIT [, ] ]
  OFFSET

DATETIME(year, month, day, hour, minute, second)
DATE(year, month, day)
TIME(hour, minute, second)
KEY ('encoded key')
USER ('email address')
GEOPT ('lat', 'long')

Слайд 12

Transactions

class Rate(db.Model):
    price = db.IntegerProperty(default=0)
    user = db.UserProperty(required=True)
    uptime = db.DateTimeProperty(auto_now=True)
    trade_unit = db.ReferenceProperty(TradeUnit, required=False)
def put_with_next_price(self,

Transactions class Rate(db.Model): price = db.IntegerProperty(default=0) user = db.UserProperty(required=True) uptime = db.DateTimeProperty(auto_now=True)
price=None):
def in_transaction(rate, next_price=None):
q = Rate.all().filter('trade_unit = ', rate.trade_unit.key())
q.order("-price")
previous_rate = q.get()
previous_price = previous_rate.price if previous_rate else next_price
price = previous_price + rate.trade_unit.increase_rate
            if rate.price < price:
                rate.price = price
            rate.put()
db.run_in_transaction(in_transaction, self, price)

Слайд 13

Entities and Keys

Key:
  Kind - объединяет по признаку (classname)
  ID - генерируется

Entities and Keys Key: Kind - объединяет по признаку (classname) ID -
Datastore или задаётся вручную
Key.from_path(kind, id_or_name, parent=none, namespace=None, **kwds)

item = TradeUnit()
item.put()
rate = Rate(parent=item)
# ................
rate = Rate(parent=item.key())

Слайд 14

Async

get
put
delete

*_async()

# выполняем какую-то работу ...

.get_result()

q = Model1.filter(...).run()

for e in q:
  ...
Async get put delete *_async() # выполняем какую-то работу ... .get_result() q

Слайд 15

NDB

Расширенное описание полей
Дополнительные типы полей db.Model
Вменяемый синтаксис запросов
Кэширование
Триггеры (hooks)

class Contact(Model):
    name = StringProperty()
    addresses

NDB Расширенное описание полей Дополнительные типы полей db.Model Вменяемый синтаксис запросов Кэширование
= StructuredProperty(Address, repeated=True)
guido = Contact(name='Guido', addresses=[
Address(type='home', city='Amsterdam'),
Address(type='work', city='SF', street='Spear St'),
])
qry = Article.query(Article.tags.IN(['python', 'GAE', 'ndb']))

Слайд 17

Google Cloud SQL

from google.appengine.api import rdbms

Google SQL Service поддерживает DB-API 2.0

etc...

Google Cloud SQL from google.appengine.api import rdbms Google SQL Service поддерживает DB-API 2.0 etc...

Слайд 18

Батарейки в комплекте:

Mail

Memcached

Message channels

Cloud storage

Images

Blobstore

Task queues

OAuth

URL fetch

MapReduce

Батарейки в комплекте: Mail Memcached Message channels Cloud storage Images Blobstore Task

Слайд 19

MapReduce:

MapReduce:

Слайд 20

Cloud storage:

Сервис общего назначения (используется в google)
AppEngine - RESTful API
Может использоваться разными

Cloud storage: Сервис общего назначения (используется в google) AppEngine - RESTful API
приложениями
Trial-only для бесплатной подписки
file-like доступ

Слайд 21

Channel API:

JS View (coffee-script sample)

    _sock = new goog.appengine.Channel @token
    @socket = _sock.open()
    # bind

Channel API: JS View (coffee-script sample) _sock = new goog.appengine.Channel @token @socket
socket events
    @socket.onopen = =>
      @subscribe options
    @socket.onmessage = (evt) =>
      console.log "realtime: ", evt
    @socket.onerror = (evt) =>
      @socket = null
    @socket.onclose = (evt) =>
      [@clients, @socket, @token] = [{}, null, null]

Python back-end:

key = str(uuid.uuid4())
def subscribe(request):
    token = channel.create_channel(request.user.id + key)
    return {
        'token': token,
    }
def send_message(request):
    channel.send_message(request.user.id + key, 'message')

Слайд 22

На этом всё

На этом всё
Имя файла: GAE:-плюсы,-минусы,-подводные-камни.pptx
Количество просмотров: 131
Количество скачиваний: 0