Anda di halaman 1dari 8

03/11/2017 Acesso a Dados AdvPL com c-Tree – Parte 01 | Tudo em AdvPL

Acesso a Dados AdvPL com c-Tree –


Parte 01
25/10/2015  Siga0984

Introdução

Depois de tantas introduções sobre acesso a dados em AdvPL, vamos descer um


degrau na implementação dos drivers c-Tree no Application Server AdvPL.
Vamos entender o que é, como funciona, o que exatamente ele faz, do que se
alimenta, como cuidar, etc…

O que é e como funciona

A empresa de software norte americana Faircom(R) disponibiliza uma engine


multi plataforma de acesso a dados ISAM e relacional, conhecida por c-Tree. A
Microsiga fez uma parceria comercial com a Faircom, para adotar o driver em
suas aplicações, como uma alternativa ao suporte de arquivos locais,
temporários e meta-dados (dicionários do ERP).

A Faircom(r) fornece as três versões do c-Tree Server ( Stand-alone ou “ctree


local”), c-Tree Server, e c-Tree Embedded ( c-Tree BoundServer ou CtreeServer
DLL), em uma build exclusiva, compatível apenas com o Application Server.

As funcionalidades são fornecidas por um conjunto de APIs, de alto e baixo


nível, que permitem a criação de arquivos ISAM, com transações ACID,
registros de tamanho fixo e variável, e um forte controle de integridade. Uma
tabela em formato DBF parece um “txt” perto do nível de controle de uma
tabela c-Tree.

APIS fornecidas junto do Application Server

Junto do pacote de executáveis do Application Server, para todas as


plataformas homologadas, são fornecidas as dlls do cTree “local” (ctreestd.dll),
API client do c-Tree Server (mtclient.dll), e um c-Tree BoundServer
(ctreecsv.dll + arquivos auxiliares).

c-Tree Local

Trata-se de uma versão stand-alone da API de acesso a dados, sem


transacionamento ou cache, que faz leitura e gravação diretamente nos
arquivos em disco. Usada pelo ERP Microsiga a partir da versão AP6 (Advanced
Protheus 6), para acessar o arquivo de senhas do ERP (sigapss.spf) e os
arquivos de help de campo por idioma (sigahl?.hl?). Estes arquivos são
conhecidos por “SuperFiles”, eles possuem uma estrutura interna fixa, onde o
mesmo container de arquivo armazena dados de tamanho variável e índices. A
https://siga0984.wordpress.com/2015/10/25/acesso-a-dados-advpl-com-c-tree-parte-01/ 1/8
03/11/2017 Acesso a Dados AdvPL com c-Tree – Parte 01 | Tudo em AdvPL

API de acesso a estes arquivos não é publicada por razões de segurança, e não é
possível chamar diretamente a API de dentro de User Functions.

Em instalações de instância única de Application Server, como por exemplo o


módulo FrontLoja do ERP (onde é instalado um Application Server e um
SmartClient nas estações de trabalho), ele pode ser usado para gerenciar uma
base local da estação, sincronizada pela aplicação com a base principal na
retaguarda do sistema.

Não deve ser usada para ambientes com mais de um Application Server
acessando o mesmo diretório raiz de ambiente (rootpath), como por exemplo
em balanceamento de carga. Caso mais de um Application Server acesse o
mesmo RootPath, é necessário utilizar um c-Tree Server.

c-Tree Server

Serviço dedicado de acesso a arquivos c-Tree, multi-thread e multi-plataforma.


Deve ser instalado na máquina física onde está armazenado o RootPath do
ambiente. Sua utilização envolve a instalação do serviço do c-Tree Server, e
alterar todos os arquivos de configuração do Application Server (appserver.ini)
para indicar que o Protheus está configurado em modo client-server com o c-
Tree(chave ctreemode=server na seção [general]), e devemos informar a URN
da instância do c-Tree Server em seção especifica (chave CTServerName na
seção [ctreeserver]). Caso não especificada, o default é FAIRCOMS@localhost.

c-Tree BoundServer (ou c-tree Server DLL, c-Tree Embedded)

Trata-se de uma compilação do c-Tree Server em DLL (creeecsv.dll), que possui


todas as funcionalidades de um c-Tree Server, mas pode ser carregado
diretamente pelo Application Server, eliminando a camada de rede no acesso a
dados. Passou a ser distribuído junto do pacote de executáveis do Application
Server a partir da build 7.00.121227P, para ser utilizada para a geração de
arquivos temporários “locais” na máquina onde está sendo executada a
instância do Application Server. Pode ser usada para gerenciar as tabelas locais
e meta-dados (dicionários do ERP), desde que a instalação não possua outro
Application Server usando a mesma pasta raiz do ambiente (rootpath).

E como o Application Server usa isso ?

Através da configuração ctreemode, na seção [general] do arquivo de


configuração do Application Server (appserver.ini), definimos qual API será
usada para acesso aos arquivos c-Tree daquela instância do servidor. Caso não
especificada, o default é “local”.

Quando o ctreemode é “local”, cada acesso a um arquivo no formato c-Tree, seja


o “superfile”, ou os meta-dados dos ambientes configurados com
localfiles=ctree, ou o driver “CTREECDX”, vão ser requisitados para a DLL do
c-Tree Local (ctreestd.dll).
https://siga0984.wordpress.com/2015/10/25/acesso-a-dados-advpl-com-c-tree-parte-01/ 2/8
03/11/2017 Acesso a Dados AdvPL com c-Tree – Parte 01 | Tudo em AdvPL

Quando informamos que o ctreemode é “server”, o Protheus carrega a dll client


do c-Tree Server (mtclient.dll), e todas as requisições para acesso aos arquivos
c-tree são realizadas para o c-tree server configurado na seção [ctreeserver].

Quando informamos que o ctreemode é “boundserver”, o protheus carrega a c-


Tree Server DLL (ctreecsv.dll), e faz todo o acesso através dela. A vantagem da
c-tree server DLL em relação ao c-Tree local, usadas em ambiente de instância
única de Application Server, é que o c-Tree Server DLL possui os caches de
leitura e escrita, que dão maior desempenho, escalabilidade e segurança para a
aplicação.

E o que ele faz de diferente de um DBF ?

Em uma palavra … TUDO. A estrutura interna de um arquivo DBF armazena


apenas dados de tamanho fixo em blocos sequenciais dentro do arquivo, e a
área de header apenas guarda a estrutura da tabela e um contador de registros.
Um arquivo DBF é praticamente um “TXT melhorado” por dentro. Não há
amarração explícita de um DBF com um arquivo indexador criado no disco. Se
você cria um índice no disco, e esquece de abrir o índice ao fazer uma inserção
ou atualização na tabela, o índice fica desatualizado, e quando você for utilizá-
lo, ene não apresenta erro, apenas deixa de encontrar as informações e se
comporta de forma errática.

Um arquivo c-Tree possui um header com os detalhes completos do arquivo,


inclusive o path completo em disco onde o mesmo foi criado. Não é uma
“tabelinha”, é um container de persistência de dados transacionados. Cada
índice permanente criado para a tabela também é registrado no header do
arquivo de dados do c-Tree. Quando você abre uma tabela c-Tree, se ela foi
trocada de diretório, ou se algum índice permanente não estiver no disco ou
não estiver sincronizado, a API retorna erro de abertura por inconsistência.

Como era possível pintar e bordar com um DBF, o Application Server verifica se
existe procedimento automático para recuperar a tabela para ela ser aberta
novamente. Se houve mudança de diretório, os índices permanentes do header
são excluídos e os paths internos são ajustados. Se apenas algum índice
permanente não foi encontrado, mas não houve mudança no path, os índices
que faltam são recriados automaticamente. Caso a tabela apresente alguma
inconsistência de abertura, como um fechamento inesperado, o Protheus
solicita um rebuild da tabela ao c-Tree.

Questões de Desempenho

Junto da segurança adicional do c-Tree, a camada de transacionamento de


arquivos provê um overhead em operações de inserção e update. Mesmo as
transações atômicas são primeiro gravadas em LOG, para depois serem
efetivadas nas tabelas. A dll do c-tree “local” não tem esta camada de

https://siga0984.wordpress.com/2015/10/25/acesso-a-dados-advpl-com-c-tree-parte-01/ 3/8
03/11/2017 Acesso a Dados AdvPL com c-Tree – Parte 01 | Tudo em AdvPL

transacionamento, tudo é escrito no disco direto. Isto passa a impressão que o


c-tree local é muito mais rápido.

E, realmente, se você coloca até 8 ou 10 conexões concorrentes em um


Application Server usando c-Tree local, o desempenho seria melhor. Porém, ao
passar de 12, 13 conexões, o desempenho dos processos começa a cair, a partir
do momento que o sistema operacional começa a enfileirar as requisições de
disco, o desempenho cai proporcionalmente conforme o volume de requisições
cresce. Quando usamos um c-Tree Server, os caches de leitura e gravação
permitem a aplicação aguentar mais requisições sem que a queda no
desempenho seja proporcional.

No ponto onde a curva de desempenho de ambos se encontra (por exemplo,


com 12 processos simultâneos c-tree local e c-tree server “empatam” no
desempenho), se dobramos a quantidade de processos, o ctree local vai ficar
duas vezes mais lento (50 % de perda) , enquanto o c-tree server perdeu apenas
15% do desempenho.

Este cenário fica muito pior quando utilizamos o c-Tree Server pela rede, pois
quanto o Application Server e o c-Tree Server estão na mesma máquina, eles
estabelecem uma conexão TCP por “loopback”, sem efetivamente usar a
interface de rede. Quando colocamos um serviço slave do Protheus em outra
máquina, cada I/O realizado para, por exemplo, ler um próximo registro da
tabela, é enviado pela rede física em um pequeno pacote TCP, e por mais rápido
que seja o seu retorno, a camada de comunicação física pode interferir no
desempenho de uma sequência de milhares de requisições em até 8 vezes. A
natureza das operações é altamente sensível a latência de rede.

Exemplo prático: Uma leitura sequencial de 20 mil registros de um


determinado arquivo, vai gerar 20 mil requisições para o c-Tree Server. Se a
minha latência de rede for 0,001 segundo (um milissegundo), mesmo que o
tempo de leitura dos dados no cache do c-Tree server seja 0 ( zero ), foram
consumidos 20 segundos na camada de comunicação. Qualquer aumento da
latência para 0,002 ou 0,003 já são suficientes para dobrar ou triplicar este
tempo.

Quando uma aplicação lê um bloco de registros retornados por uma Query do


SGDB, e vai criar uma tabela temporária no ERP (usando a CriaTrab() por
exemplo), esta tabela é criada dentro da pasta “\system\” do diretório raiz do
ambiente, onde cada inserção de registro faz um I/O pela rede ao c-Tree Server,
que cria no disco uma tabela com transacionamento completo (chamado pela
Faircom de acesso “TRNLOG”). Então, além do overhead da camada de rede,
você têm um transacionamento completo com o dobro de escrita em disco.

Outro ponto é a escalabilidade de leitura. Mesmo com caches de leitura, a rede


representa um overhead significativo. Se conseguimos jogar tudo na mesma
máquina, tudo é lindo. Porém, se o seu ambiente cresce e você precisa suportar
mais conexões e mais instância de processamento do Application Server,
https://siga0984.wordpress.com/2015/10/25/acesso-a-dados-advpl-com-c-tree-parte-01/ 4/8
03/11/2017 Acesso a Dados AdvPL com c-Tree – Parte 01 | Tudo em AdvPL

escalar esta máquina verticalmente não é viável, e mais cedo ou mais tarde você
vai esbarrar em um limite físico. A sua super-máquina teria que ter várias
placas de rede para evitar contenção, muitos cores, e uma placa mãe com
barramentos “sinistros” pra aproveitar o que for possível de paralelismo…

E agora ? O que fazer ?

Primeiramente, pensando em escalabilidade horizontal, ao colocarmos mais


máquinas físicas em um cluster, quanto mais servidores forem colocados, mais
processos vão realizar requisições simultâneas de acesso de leitura dos meta-
dados do ERP pela rede. Em um ambiente com 100, 120 conexões simultâneas,
isto pode não apresentar contenção. Porém, quando passamos de 150 conexões
fazendo I/O simultaneamente, a rede pode se tornar um gargalo.

Muita atenção neste ponto: Não é a banda de rede que torna-se o gargalo, mas
sim a quantidade de IOs, o enfileiramento dos pacotes para transmissão e
recepção atinge um limite físico. Mesmo que a sua banda de rede suporte 1 GB
por segundo, e o consumo de banda chega a menos de 20% deste valor, a
quantidade de pacotes é tão grande que a rede não dá conta dos eventos e
começa a “enfileirar”.

Pensando neste cenário, a TOTVS homologou junto da Faircom um mecanismo


de cache dos meta-dados (dicionários) do ERP sincronizado em memória. A
idéia é simples, mas a implementação por baixo do capô exigiu um mecanismo
de sincronismo complexo, mas de uma eficiência impressionante.

Dicionários em Memória usando c-Tree

Vamos partir de um ambiente padrão, onde a máquina que contém a unidade


de disco onde estão os arquivos da pasta raiz do sistema (RootPath) possui o c-
tree Server instalado, e uma segunda máquina possua um serviço do
Application Server, configurado com ctreemode=server. Todos os IOs de leitura
passam pela rede.

Agora, imagine que este Application Server possa ser iniciado usando a DLL do
c-Tree Server (BoundServer), e você configure no INI deste Application Server
quais serão os arquivos do seu ambiente que serão cacheados na memória, e
este cache possui um mecanismo de notificação de alterações de dados, para
manter todos os nós sincronizados caso algum processo de algum slave faça
alguma alteração em um registro de uma tabela no c-Tree SErver que esteja em
cache em um ou mais nós ? Isto seria lindo, pois todas as leituras seriam feitas
diretamente da cópia da tabela feita em memória no Ctree BoundServer que o
Application Server carregou … Escalabilidade horizontal “plena”, pode enfiar nó
nesse cluster, que uma vez que o cache esteja carregado, tudo é lido da
memória.

É exatamente isso que o mecanismo de cache e de notificação fazem. Cada


Application Server configurado com o modo BoundServer, mais a configuração
https://siga0984.wordpress.com/2015/10/25/acesso-a-dados-advpl-com-c-tree-parte-01/ 5/8
03/11/2017 Acesso a Dados AdvPL com c-Tree – Parte 01 | Tudo em AdvPL

de cache em memória — definida no appserver.ini na seção [ctreeservermaster]


— vai conectar com o c-Tree Server no momento da subida do serviço do
Application Server, vai verificar quais as tabelas que devem ser trazidas para a
memória, vai abrir uma a uma e copiar os dados para a memória local do c-Tree
BoundServer, e vai registrar-se no c-Tree Server como um nó cliente de cache.
A partir daí, todas as leituras das tabelas que entraram no cache são feitas da
memória local, e qualquer alteração que qualquer um dos nós faça nesta tabela
vai refletir instantaneamente na cópia da tabela na memória do Protheus Server
que alterou u registro, e na tabela principal no disco. Quando o c-Tree Server
gravar a alteração da tabela no disco, ele envia uma notificação para todos os
demais serviços de Protheus configurados como bound-Servers, avisando que
eles devem pegar uma cópia atualizada do registro alterado para manterem os
seus caches sincronizados. Para isso, um Application Server configurado desta
forma vai abrir uma conexão pela rede com o c-Tree Server, para receber as
notificações de atualizações de cache, e cada tabela que está na memória deste
BoundServer vai ser aberta por este Application Server pela API do
boundServer, e pela conexão de rede com o c-Tree Server, onde esta conexão
somente será utilizada se a aplicação fizer um insert ou lock e update em algum
registro.

Mas, quanto isso consome de recurso ?

Bem, cada tabela configurada no mecanismo de cache em memória precisa ser


carregada inteira para a memória, bem como os seus índices. A carga não é sob
demanda, é feita na subida do Application Server. O espaço médio em memória
do Application Server utilizado é aproximadamente duas vezes o tamanho do
arquivo de dados mais os índices. Por exemplo, um arquivo SX3990.DTC com
169 MB e seu índice de 10 MB, vão ocupar 350 MB da memória deste
Application Server. Por esta razão, a configuração de réplica realmente deve
priorizar apenas os dicionários do ERP mais acessados, e no caso do ambiente
ter múltiplas empresas (e consequentemente múltiplos arquivos de dicionário),
devem ser priorizados apenas os arquivos das empresas mais acessadas.

Devido ao alto consumo de memória por instância de Application Server, e


devido a cada serviço de Protheus criar um cache apenas para si mesmo,
quando você possui máquinas maiores, que comportam por exemplo 8
instâncias de Application Server na mesma máquina, isso gerada dois
inconvenientes: O primeiro é que o startup do ambiente iniciava uma cópia
maciça de dados para cada um dos serviços da mesma máquina, onde o serviço
poderia demorar muito para estar disponível para a execução dos programas
AdvPL. E, como cada serviço criava uma cópia para si mesmo, você teria oito
vezes o consumo de memória para um cache no mesmo equipamento.

Pensando nisso, foi criado um modo de configuração chamado “boundclient”.


Você elege um dos outro serviços para ser retirado do balanceamento de carga,
para ele não receber requisições de conexão de SmartClient ou fazer qualquer
processamento Advpl. Este serviço você configura como um BoundServer com o
https://siga0984.wordpress.com/2015/10/25/acesso-a-dados-advpl-com-c-tree-parte-01/ 6/8
03/11/2017 Acesso a Dados AdvPL com c-Tree – Parte 01 | Tudo em AdvPL

cache de arquivos na memória, e habilita a conexão TCP no c-Tree BoundServer


desta instância (depois te explico como). Para todos os outros demais serviços,
eles serão configurados exatamente como este primeiro boundServer, apenas
trocando a
chave ctreemode=boundserver para ctreemode=boundclient

Com este cenário, o primeiro serviço que deve ser colocado no ar é o


Application Server configurado para ser o BoundServer. Somente ele vai fazer a
cópia dos arquivos para a memória, uma vez. E, todos os demais serviços de
Protheus desta máquina vão conectar-se neste BoundServer para ler a cópia dos
dados em memória. Isso economiza horrores no tempo de iniciar o ambiente, e
economiza a memoria da máquina, pois nela haverá apenas uma instância de
serviço dedicada a prover o cache e mantê-lo sincronizado.

E isso resolve tudo ?

Não. Como o c-Tree Server também vai ser usado como o driver para a criação
de arquivos locais de trabalho, que por default são criados dentro da pasta
‘\system\’ do diretório raiz do ambiente (rootpath), todos os IOs de leitura e
gravação ainda passam pela rede … Por isso, também na Build 7.00.121227, foi
criado um novo driver, chamado “CTREETMP”, encapsulado pelas funções
FWOpenTemp() e FwCloseTemp(), para permitir criar um arquivo temporário
“puro”, aberto e acessado exclusivamente pelo processo que o criou em modo
exclusivo, e que é criado na pasta temporária do servidor onde o Application
Server está sendo executado, carregando para isso em memória uma instância
do c-Tree BoundServer, e criando uma tabela sem nenhum controle de
transacionamento. Com isso, todos os IOs feitos para esta tabela temporária
serão tão ou mais rápidos que um c-Tree “local”.

O driver “CTREETMP” têm uma diferença em relação aos demais recursos de


acesso do c-Tree. Mesmo que o seu application server esteja configurado com
ctreemode=local ou ctreemode=server, quando um programa AdvPL usar o
Driver temporário CTREETMP pela primeira vez, o protheus vai carregar uma
instância do c-Tree BoundServer para gerenciar os arquivos temporários
acessados por este driver. Todo o resto fica inalterado. Caso o seu modo de
trabalho já seja ctreemode=boundserver, o protheus já aproveita a instância do
BoundServer carregada para gerenciar os arquivos do driver temporário
“CTREETMP”.

Aí sim, com os programas AdvPL criando as tabelas temporárias de trabalho


usando o encapsulamento do Framework para o Driver temporário, e a leitura
dos meta-dados do ERP em um cache de memória distribuído e sincronizado, a
coisa muda de figura !

E, o que eu preciso ?

https://siga0984.wordpress.com/2015/10/25/acesso-a-dados-advpl-com-c-tree-parte-01/ 7/8
03/11/2017 Acesso a Dados AdvPL com c-Tree – Parte 01 | Tudo em AdvPL

Não basta configurar o circo todo … Existe a necessidade de adquirir uma


licença “Enterprise” do c-Tree Server para conseguir habilitar este cache. O c-
Tree Server e o c-Tree BoundServer distribuídos pela TOTVS possuem uma
licença de uso apenas para arquivos locais, não é possível usá-lo como base
principal do ERP (RPODB=CTREE) ou com o sistema de cache de dicionários
em memória. Uma vez adquirida e aplicada uma licença “Enterprise” no c-Tree
Server, é possível usufruir deste mecanismo de cache.

Conclusão

Como o assunto é extenso e cheio de detalhes, este post foi só para “abrir” o
apetite. A documentação oficial do recurso de cache de dicionários em memória
foi recentemente disponibilizada na TDN, veja os links de referência do post no
final do artigo !

Espero que estas informações sejam de alguma forma valiosas e aproveitadas


para que possamos cada vez mais utilizar todo o potencial computacional
disponível graças ao avanço da micro-informática.

Desejo a todos TERABYTES de sucesso 

Referências

C-treeACE. (2014, November 29). In Wikipedia, The Free Encyclopedia.


Retrieved 16:14, October 25, 2015,
from https://en.wikipedia.org/w/index.php?title=C-
treeACE&oldid=635850139

Documentação da TDN

c-Tree Server com SXS em memória


Seção cTreeServerMaster
Seção ctreeServer
ctServerName
cTreeMode
c-tree BoundServer

https://siga0984.wordpress.com/2015/10/25/acesso-a-dados-advpl-com-c-tree-parte-01/ 8/8

Anda mungkin juga menyukai